bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 避免浮點數操作的四捨五入錯誤
查看: 5341|回復: 1
go

避免浮點數操作的四捨五入錯誤 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2006-6-23 13:58 |只看該作者 |倒序瀏覽 |打印
Single, Double 和 Extended 型的浮点变量存在著四捨五入問題。
举个例子,假设我们用电脑使用4位数字,那么:

  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 ,浮点类型可以给你更好的精确度,但是上述的四舍五入错误依然存在。

不要再作相等比较了,我们需要确定要多精确才够。

用下面的例程实现:
  1. var
  2.   ESBTolerance: Extended = 0.00000001; //设定所要的精确度

  3. function SameFloat (const X1, X2: Extended): Boolean;
  4. begin
  5.   Result := abs (X1 - X2) < ESBTolerance
  6. end;

  7. function FloatIsZero (const X: Extended): Boolean;
  8. begin
  9. Result := abs (X) < ESBTolerance
  10. end;

  11. function FloatIsPositive (const X: Extended): Boolean;
  12. begin
  13. Result := (X >= ESBTolerance);
  14. end;

  15. function FloatIsNegative (const X: Extended): Boolean;
  16. begin
  17.   Result := (X <= -ESBTolerance);
  18. end;
複製代碼
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw

Rank: 9Rank: 9Rank: 9

2#
發表於 2008-2-13 13:34 |只看該作者
關於 小數->整數 的函數,總共有 4 個
Ceil (天花板),無條件往數線的正向靠攏
Floor (地板),無條件往數線的負向靠攏
Trunc,無條件往數線 0 的位置靠攏
Round,以"四捨六入五成雙"的原則,往最近的整數靠攏

奇怪了,不是"四捨五入"嗎?怎麼來個"四捨六入五成雙"呢?
請看 Help 中有關 Round 的一段文字:
X is a real-type expression. Round returns an Int64 value that is the value of X rounded to the nearest whole number. If X is exactly halfway between two whole numbers, the result is always the even number.
紅色部分明白指出"五成雙"
舉例說明:
Round(1.5) 結果是 2
Round(2.5) 結果也是 2
Round(1.51) 結果是 2 (not exactly halfway)
Round(2.51) 結果是 3 (not exactly halfway)


from http://delphi.ktop.com.tw/board.php?tid=29498
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-5-1 04:49 , Processed in 0.010461 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.