2014-02-06 49 views
3

我有一段簡單的代碼如下。bcmul報告0

$amount = 447274.44882; 
$rate = 0.00001; 

echo floatNumber(bcmul($amount, $rate, 8), 8); 

當它應該是4.47274449時,它輸出0.00000000。如果我改變率0.0001然後將其輸出正確的號碼,任何超過4個小數高,它報告0

我做得不對或這是一個已知的限制還是什麼?如果是這樣的話,看起來很大。

+1

即使沒有看到什麼'floatNumber()'做:用bcmath時用浮漂,而不是字符串完全擊敗目的。 –

+0

嘗試使用此sprintf的http://in1.php.net/sprintf就像是你幾乎類似的情況http://stackoverflow.com/questions/21598667/php-the-awk-subtraction-giving-exponential-values/21599099# 21599099 –

+0

它呢?我希望它能解決我的舍入錯誤。我會用字符串嘗試一下,看看它是否有效。 – Linkandzelda

回答

2

如果使用默認設置投0.00001串(這就是,如果你因爲它expects strings飼料bcmul花車會發生什麼事),你會得到這樣的:

var_dump((string)0.00001); 
string(6) "1.0E-5" 

這是不明確記錄,但bcmath功能明顯返回在面對無效輸入時投入零:

var_dump(bcadd('Hello', 'world!', 8)); 
var_dump(bcadd('33', 'Foo', 8)); 
var_dump(bcdiv('33', 'Foo', 8)); 
string(10) "0.00000000" 
string(11) "33.00000000" 
Warning: bcdiv(): Division by zero 
NULL 

任意精度文庫的整個想法是克服基座2的算術和固定大小的存儲的限制。因此,你需要這樣的:

var_dump(bcmul('447274.44882', '0.00001', 8)); 
string(10) "4.47274448" 

這是偉大的,做數學與100位數字,但對於簡單的四捨五入不是特別有用。事實上,延長不一輪全它只是截斷

var_dump(bcmul('20.01', '1.444', 3)); 
var_dump(bcmul('20.01', '1.444', 2)); 
var_dump(bcmul('20.01', '1.444', 1)); 
var_dump(bcmul('20.01', '1.444', 0)); 
string(6) "28.894" 
string(5) "28.89" 
string(4) "28.8" 
string(2) "28" 
+0

這個答案非常詳細,謝謝。我仍然不知道如果使用BCmul,即使在字符串之間進行投射時也會導致計算結果不準確,但會產生大數字的8位浮點數。 – Linkandzelda

+0

由於IEEE浮點精度的工作原因,您可能*得到不準確的計算結果。但是現實生活中的大部分時間都是因爲在錯誤的地方四捨五入(或者根本不是四捨五入)。你總是可以使用*整數*(例如,美分而不是歐元)。 –