這個測試代碼:
$data = array(
12.12234,
1.01
);
foreach($data as $fMyFloat){
echo sprintf('%18.016f', $fMyFloat) . PHP_EOL;
}
...打印這在我的64位計算機:
12.1223399999999994
1.0100000000000000
您所面臨的浮點精度的衆所周知的問題。將基數爲10的整數轉換爲基數2非常簡單(確切),但基數10浮點數不一定總是以基數2表示。此問題並非針對PHP,而是PHP手冊中的warning:
浮點數的精度有限。雖然它取決於系統,但PHP通常使用IEEE 754雙精度格式,即 ,由於以1.11e-16的順序 進行四捨五入,因此它會給出最大相對誤差。非基本的算術運算可能會給出更大的錯誤,當然,當幾個操作複合時,必須考慮錯誤傳播。
此外,有理數是在基座10,如0.1或0.7精確表示作爲 浮點數,沒有一個 精確表示作爲浮點數在基座2,其是 內部使用,不管尾數的大小。因此,他們 不能轉換成內部二進制的格式不精密
你只有達到這樣的精度可能有 小的損失是處理數字爲字符串。 PHP捆綁了兩個任意精度庫,可以幫助您在需要與字符串匹配時:GNU Multiple Precision和BC Math。這裏有一個小黑客與bcmath時:
$data = array(
'12.12234',
'1.01'
);
bcscale(16);
foreach($data as $fMyFloat){
echo bcdiv($fMyFloat, 1) . PHP_EOL;
}
這這種情況下,雖然,你也許可以使用簡單的字符串函數:上期
$data = array(
'12.12234',
'1.01'
);
foreach($data as $fMyFloat){
list($a, $b) = explode('.', $fMyFloat);
echo $a . '.' . str_pad($b, 16, 0) . PHP_EOL;
}
分裂,攻擊與['str_pad'(HTTP:/ /php.net/str_pad)? – Charles
我已經嘗試過這種方法,但我認爲它應該可以與sprintf一起使用。但我無法弄清楚如何。看起來當你漂浮超過9個數字後,它應該被視爲不同。 – Ben