2011-03-04 37 views
18

的結果我預計結果是87.29。我也試過SimpleRoundTo,但是產生了相同的結果。爲什麼RoundTo(87.285,-2)=> 87.28

在幫助中也有一個「奇怪」的例子: MS-幫助://embarcadero.rs2010/vcl/Math.RoundTo.html

RoundTo(1.235, -2) => 1.24 
RoundTo(1.245, -2) => 1.24 //??? 

有誰知道哪些功能我需要得到87.29的結果?我的意思是:如果最後一位數字大於等於5,那麼如果< 5輪下來。正如學校所教導的:)

我使用的是Delphi2010和SetRoundMode(rmNearest)。我也試過rmTruncate。 值87.285存儲在double變量中。

來也怪:

SimpleRoundTo(87.285, -2) => 87.29 

x := 87.285; //double 
SimpleRoundTo(x, -2) => 87.28 
+3

Google「銀行家四捨五入」 – 2011-03-04 08:18:57

+2

正如David和Rob在下面討論的那樣,上面的評論並沒有起初的那麼好。 – 2011-03-04 17:32:44

回答

19

87.285不能準確地表示,最近的雙略小。

有關浮點的經典參考是What Every Computer Scientist Should Know About Floating- Point Arithmetic

對於基於貨幣的計算,如果確實如此,則應該使用基數爲10的數字類型而不是基數爲2的浮點數。在德爾福,這意味着Currency

+3

+1。四捨五入通常只有在處理金錢時纔是關鍵的,爲了錢我們應該使用貨幣。貨幣可以表示該數字,舍入將正確舍入。 – 2011-03-04 08:31:10

+0

我似乎總是把人們指向那篇文章。人們似乎認爲浮點數具有超出其真實能力的能力。就像代表三分之一的能力一樣。四捨五入的銀行家也讓很多人感到驚訝。 – 2011-03-04 15:16:28

+0

貨幣始終是基數2的值,但是是一個整數值(儘管通過FPU,IIRC進行管理)會自動縮放爲小數點後四位(固定)。二進制編碼的小數是使用TBCD實現的。使用變體可以輕鬆操作(請參閱VarFMTBCDCreate)。 – 2011-03-08 17:11:33

25

精確值87.285在Delphi中不能表示爲浮點值。 A page on my Web site顯示了該值確實是,作爲擴展,雙和單:

 
87.285 = + 87.28500 00000 00000 00333 06690 73875 46962 12708 95004 27246 09375 
87.285 = + 87.28499 99999 99996 58939 48683 51519 10781 86035 15625 
87.285 = + 87.28500 36621 09375 

默認情況下,在Delphi浮點文字有型的擴展,並且你可以看到,你的電話號碼的擴展版本略高於87.285,所以到最近的四捨五入是正確的。但是,作爲一個Double,實數稍低。這就是爲什麼如果您在撥打RoundTo之前明確將該號碼存儲在Double變量中,您將得到您期望的號碼。每個Delphi的浮點類型都有該函數的重載。

+2

+1喜歡你的網站上的網頁!自動回答所有這些問題! – 2011-03-04 09:29:09

+0

+1這個偉大的頁面是爲什麼我對[Good Delphi Blogs]感興趣的主要原因(http://stackoverflow.com/questions/2975586/good-delphi-blogs)! – 2011-03-04 12:29:08

相關問題