[Delphi] 避免浮點數型態變數運算的四捨五入錯誤
這是一個令程式設計師有些傷腦筋的問題,在網路上找到此簡體版的技術文件,作者未知,記錄起來當筆記。
資料型態 為 Single、Double 和 Extended 的浮點數變數存在著四捨五入的問題。舉個例子,假設我們用電腦使用小數四位,那麼:
1 / 3 = 0.3333
我們都知道 3 * 1 / 3 = 1 但如果我們這樣
X := 1 / 3;
X := X * 3;
if X = 1 then //比對結果將會不正確
為什麼呢?
因為 X = 0.9999 而不是 1
電腦不會有無限的小數點。從 Single 到 Double 到 Extended 的浮點數類型雖然可以給你更好的精確度,但是上述的四捨五入的錯誤依然存在。
所以不能做相等比較了,我們需要確定要多精確才夠。
用下面的程式來處理:
var
ESBTolerance: Extended = 0.00000001; //設定所要的精確度
function SameFloat (const X1, X2: Extended): Boolean;
begin
Result := abs (X1 – X2) < ESBTolerance
end;
function FloatIsZero (const X: Extended): Boolean;
begin
Result := abs (X) < ESBTolerance
end;
function FloatIsPositive (const X: Extended): Boolean;
begin
Result := (X >= ESBTolerance);
end;
function FloatIsNegative (const X: Extended): Boolean;
begin
Result := (X <= -ESBTolerance);
end;
15 4 月, 2011 at 16:34
Sorry,您的計算式有問題
3 * 1 / 3 = 1 應該是
X=3*1
X=X/3
這樣if X=1 就會是True了
15 4 月, 2011 at 16:41
Sorry,再補充一下
若 X := 1 / 3;
X := X * 3;
not X = 1
那記算式應為
3 * (1 / 3) = 0.3333
17 4 月, 2011 at 23:41
嗯, 應該是 3 * (1 / 3) = 1
17 4 月, 2011 at 23:50
或是說受到計算過程的影響會得到 3 * (1 / 3) = 0.9999 這樣的結果.