2012-12-18 39 views
0

我想獲得浮動(18,16)與填充零的權利,但這是行不通的,因爲它總是以1而不是零結束。我的猜測是因爲我指定了錯誤,但我不確定如何正確執行。Sprintf浮動18,16浮動與正確的填充零

樣品: 12.12234必須成爲12.1223400000000001.01必須成爲1.01000000000000

爲了達到這個目的,我使用了sprintf('%18.016f', $fMyFloat);,但是這總是以1而不是0結尾。顯然,我在監督一些事情,我只是不知道該怎麼做。任何幫助是極大的讚賞。

+1

分裂,攻擊與['str_pad'(HTTP:/ /php.net/str_pad)? – Charles

+0

我已經嘗試過這種方法,但我認爲它應該可以與sprintf一起使用。但我無法弄清楚如何。看起來當你漂浮超過9個數字後,它應該被視爲不同。 – Ben

回答

3

這個測試代碼:

$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 PrecisionBC 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; 
} 
+0

感謝您的明確解釋。哇。你知道這個東西!這超出了我的知識範圍,我不會想到這一點。謝謝+1,並被接受。先生,祝你有美好的一天。 (你說得對,我正在尋找我以前的str_pad解決方案(就像你的))。 – Ben