浮點數運算與數值表示

浮點數運算

科學家用科學記號寫極大或極小的數,例如 6.022 * 10^23 或 1.6 * 10^(-19):幾個有效數字乘上一個 10 的次方,把小數點滑到需要的位置。浮點數運算(floating-point arithmetic)就是電腦版的這個想法,但以 2 為基底進行:它保留固定數目的有效位元,並透過儲存的指數讓二進位小數點浮動,於是單一的 64 位元字組就能同時描述一個星系的質量與一顆原子的大小。

每一個基本運算——加、減、乘、除、開平方——都先取其真正的實數結果,再把它捨入到最接近的可表示浮點數。標準的建模方式是 fl(x op y) = (x op y)(1 + delta),其中 |delta| <= u,u 是單位捨入(unit roundoff):每一個單一運算都準確到只差一個極小的相對抖動。硬體(概念上)確實先算出精確結果再捨入一次,所以單一運算的準確度已是該格式所能達到的極限。

關鍵的誠實之處:浮點運算並不是實數運算。可表示的數有限且間距不均,所以熟悉的定律可能失效——加法不滿足結合律,(a + b) + c 可能不等於 a + (b + c),而 0.1 + 0.2 也不會恰好等於 0.3。每個運算幾乎都精確,但誤差會在數百萬次運算間累積,而一個粗心的公式可能在單次相減中就喪失幾乎所有數字。數值計算的全部技藝,就在於安排計算使這些微小、可理解的誤差保持微小。

在雙精度中,0.1 + 0.2 算出來是 0.30000000000000004,而非 0.3,因為 0.1 與 0.2 都沒被精確儲存,而捨入後的和落在 0.3 最接近的可表示值上方一格。因此判斷式 (0.1 + 0.2 == 0.3) 會回傳 false——這是初學者經典的震撼,卻是完全正確的行為。

每個運算都捨入;微小的表示誤差隨後傳播開來。

單一浮點運算幾乎完美(相對誤差 <= u);危險在於運算的「序列」。切勿用精確相等去比較兩個算出來的浮點數——應以一個依數值大小縮放的容差來比較。

又稱
FP arithmeticfloating-point computation浮點運算