2010-11-21 133 views
5

echo (int) ((0.1+0.7) * 10);PHP整數舍入問題

爲什麼上面的輸出是7?我理解PHP如何向0進行舍入,但不是將(0.1+0.7) * 10評估爲浮點數,然後將其作爲整數進行轉換?

謝謝!

+0

我認爲這發生在任何語言,因爲浮點數的處理方式是內部的 – Quamis 2010-11-21 07:37:00

回答

7

當小數內部轉換爲二進制等效值時,會出現精度損失。計算出的值將類似於7.9+而不是預期的8.

如果您需要高度的準確性,請使用GMP函數族或bcmath函數庫。

+0

+1像'bcmath'這樣的庫是最好的選擇。 – 2010-11-21 02:46:15

0

我沒有安裝PHP,但在python:

$ python 
>>> 0.1+0.7 
0.79999999999999993 
>>> 

不在基地10所有號碼可恰恰在基地2系統來表示。檢查維基百科條目:二進制

部分分數。特別是,這條線:

Fraction Decimal  Binary Fractional Approx. 
1/10 0.1  0.000110011... 1/16+1/32+1/256... 

1/10不能在基座2。因此一個有限的方式來表示,0.1 + 0.7不能精確在鹼計算2.

決不假設浮點點計算是精確的,它會遲早咬你。

2

參見手冊:

http://php.net/manual/en/language.types.float.php

典型的是簡單的小數 餾分像0.1或0.7不能 轉化爲它們的內部二進制 同行而不 精度小的損失。這可能導致混淆 結果:例如, floor((0.1 + 0.7)* 10)通常將 返回7而不是預期的8, ,因爲內部表示將 類似7.9。

0

1/10不能用有限數量的二進制數字表示,就像1/3不能表示爲有限數量的基數爲10的數字一樣。所以你實際上加在一起0.09999999999999 ...和0.69999999999999 ... - 總和是差不多是 8,但不是很完美。

1

其他答案解釋爲什麼會發生這種情況。這應該得到你想要的東西:

echo (int) round((0.1+0.7) * 10); 

只是浮動強制轉換爲int之前。

+0

另外,它的建議你實際上並沒有使用浮點數進行貨幣計算,因爲這種精度的損失 – Quamis 2010-11-21 07:36:04