我有一个简单的代码如下。

$amount = 447274.44882;
$rate = 0.00001;

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

当它应该是4.4727449时,输出0.00000000。如果我把速率改为0.0001,它就会输出正确的数字,任何大于4位小数的都会报告0。
我是做错了什么,还是这是一个已知的限制?如果真是这样的话,似乎是一个很大的问题。

最佳答案

如果使用默认设置将0.00001强制转换为字符串(如果使用float输入bcmul,则会发生这种情况,因为它expects strings),则会得到:

var_dump( (string)0.00001 );

string(6) "1.0E-5"

虽然没有明确的文档记录,但是bcmath函数在面对无效输入时显然会将cast返回到零:
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"

关于php - Bcmul报告0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21609030/

10-10 08:28