close
剛剛在算一組數字,全都是兩位小數的加法,原本預期是:
6676.18 + 339.37 + 3667.65 + 1204.70 + 4286.02 = 16173.92
但實際計算結果卻令人震驚!
6676.18 + 339.37 + 3667.65 + 1204.70 + 4286.02 = 16173.920000000002
後面的 "0000000002" 哪來的啦!
我以前只在 JavaScript 遇到過,印象中強者我同事有跟我說他踩過這個雷,但是 telegram 和 LINE 的搜尋實在是太令人無言了,翻遍 blog 我竟然沒寫下來,只好摸摸鼻子自己重新搜尋。
原理可參考這幾篇:
- "Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?"
裡面介紹到,小數在電腦裡是找一個接近的數字,並非精確表達,所以在相加之後尾巴會跑出來,如果要做貨幣的計算,要使用貨幣專用的型別、或是加上四捨五入、或是先用整數計算再換回小數(常見作法就是兩位小數先都乘以 100、加總後再除以 100)。 - 《PHP 浮點數運算後的比對陷阱》,裡面提到這是因為浮點數計算會有差分,用 bcadd() 可解決。
最後我選擇用 bcadd 這個 function,它的參數是這樣:
bcadd ( $第一個浮點數, $第二個浮點數, 結果需要的小數位數)
所以我就把我的總合加個零,希望得到正確的 2 位小數:
$total = bcadd(0, $total, 2);
打完收工~
文章標籤
全站熱搜
留言列表