2017-03-15 36 views
-2

當我運行這個PHP(31年4月5日,在32位Windows XP上運行)的代碼,我得到的結果,我期望:PHP,爲<=不帶有小數預期的結果

for($i = 0; $i <= 10; $i = $i + 0.5) 
    echo $i .' '; 

但如果我移動小數點過像這樣:

for($i = 0; $i <= 1; $i = $i + 0.05) 
    echo $i .' '; 

儘管<=條款,循環退出在0.95,而不是在1

我知道,有一個不確切的性質,浮點數,但這似乎很友善f極端。

+0

「但這似乎有點極端」---以什麼方式?如果你明白某些數字不能精確表示,那麼如何增加不精確的數字會導致不準確的驚喜?爲了簡單起見,假設'0.5'文字的實際值(參見「最接近的可表示的」)是'0.51',現在嘗試手動評估您的代碼。 – zerkms

+0

我懷疑這正是您提到的浮點精度問題。爲了好玩,請嘗試使用不同編程語言(例如Javascript)完全相同的代碼。出於完全相同的原因,您可能會發現完全相同的「不正確」行爲。 – adfaklsdjf

+1

@zerkms也許我做錯了,但是當我在我的chrome javascript控制檯中嘗試代碼時,它會在達到100之前停止,並且我可以看到不精確度在踢,如我在下面的答案中所述。 – adfaklsdjf

回答

-1

我意識到還有一個簡單的解決方案,使用round()

for($i = 0; $i <= 1; $i = round($i + 0.05,2)) 
    echo $i .' '; 

其他的答案是更好不過。謝謝!我應該只讀過關於浮動的PHP手冊頁。

3

這是如何表示浮點數的問題。爲了解決這個問題,我建議改變你的代碼中使用整數索引所以,

for($i = 0; $i <= 100; $i = $i + 5) 
    echo ($i/100) .' '; 

這樣,你只是被100再除以i 100內循環,以獲得浮數的係數來換算指標向上你要。

1

我懷疑這是像你在你的問題中暗示的浮點精度問題。

例如,請嘗試以下的javascript:

for($i = 0; $i <= 1; $i = $i + 0.5) { console.log($i + " "); } 

VS

for($i = 0; $i <= 1; $i = $i + 0.05) { console.log($i + " "); } 

你會看到相同的行爲,你會看到浮點不精確飼養它的頭:

0 
VM4901:1 0.05 
VM4901:1 0.1 
VM4901:1 0.15000000000000002 
VM4901:1 0.2 
VM4901:1 0.25 
VM4901:1 0.3 
VM4901:1 0.35 
VM4901:1 0.39999999999999997 
VM4901:1 0.44999999999999996 
VM4901:1 0.49999999999999994 
VM4901:1 0.5499999999999999 
VM4901:1 0.6 
VM4901:1 0.65 
VM4901:1 0.7000000000000001 
VM4901:1 0.7500000000000001 
VM4901:1 0.8000000000000002 
VM4901:1 0.8500000000000002 
VM4901:1 0.9000000000000002 
VM4901:1 0.9500000000000003 

如果你需要像這樣的浮點精確迭代,也許考慮在迭代過程中相乘,舍入和轉換爲整數。

+1

我使用Stripe作爲支付網關,將數據從自制購物車系統遷移到了現成的系統。自制系統使用美元金額的浮點數。現成的系統和Stripe的API使用整數美分。我在遷移數據時發現,有時候我有一分一分的問題。我拉了一會兒頭髮,然後意識到這是浮點不精確。有一個特定的數字導致問題一直存在1.13美元或13.30美元。我不記得,也不想。 – adfaklsdjf

+0

這很有趣。我不會想到爲美分使用單獨的int值。很高興知道這是要注意的事情。 –

+0

兩個整數,一個用於美元,另一個用於美分,但是購物車系統和Stripe的API都使用一個整數。例如。 53.25美元的金額將代表5325.這就是我所說的「整數美分」:五千三百二十五美分。 – adfaklsdjf