注意浮點不準確

浮點數不能代表所有實數。這稱為浮點不準確。

存在無限多個浮點數並且它們可以無限長(例如,π),因此能夠完美地表示它們將需要無限量的儲存器。看到這是一個問題,設計了計算機中實數儲存的特殊表示,即 IEEE 754 標準 。簡而言之,它描述了計算機如何儲存這種型別的數字,帶有指數和尾數,如,

floatnum = sign * 2^exponent * mantissa

對於這些中的每一個,只有有限的位數,只能實現有限的精度。數字越小,可能數字之間的差距越小(反之亦然!)。你可以在此線上演示中嘗試你的實數。

請注意此行為並嘗試避免所有浮點比較以及它們在迴圈中用作停止條件。見下面的兩個例子:

示例:完成浮點比較錯誤:

>> 0.1 + 0.1 + 0.1  == 0.3

ans =

  logical

   0

如前例所示,使用浮點比較是不好的做法。你可以通過獲取差異的絕對值並將其與(小)容差級別進行比較來克服它。

下面是另一個示例,其中浮點數用作 while 迴圈中的停止條件:**

k = 0.1;
while k <= 0.3 
  disp(num2str(k));
  k = k + 0.1;
end

% --- Output: ---
0.1
0.2

它錯過了最後一個預期的迴圈(0.3 <= 0.3)。

示例:完成浮點比較右:

x = 0.1 + 0.1 + 0.1;
y = 0.3;
tolerance = 1e-10; % A "good enough" tolerance for this case.

if ( abs( x - y ) <= tolerance )
  disp('x == y');
else
  disp('x ~= y');
end

% --- Output: ---
x == y

有幾點需要注意:

  • 正如所料,現在 xy 被視為等效。
  • 在上面的例子中,公差的選擇是任意的。因此,所選擇的值可能並不適合所有情況(特別是在使用小得多的數字時)。智慧選擇繫結可以使用 eps 函式完成,即 N*eps(max(x,y)),其中 N 是一些特定於問題的數字。對於 N 來說,合理的選擇也是允許的,但是,即使在上面的問題中,N=1 也足夠了。

進一步閱讀:

有關浮點不準確的更多資訊,請參閱以下問題: