为什么bccomp比较平等?

时间:2015-11-18 11:54:44

标签: php floating-point

我通常通过比较浮点数差异的绝对值和任意小的delta来测试浮点数比较:

php > echo abs( (0.1+0.1+0.1) - 0.3 ) < 0.0001 ;
1
php > echo abs( 0.3 - (0.1+0.1+0.1) ) < 0.0001 ;
1

今天我发现了PHP函数bccomp(),它应该执行比较,但它确实要求它的参数为字符串(如果值实际上相等则返回0)!

来自fine manual,并在我的PHP解释器中确认:

echo bccomp('1', '2') . "\n";   // -1
echo bccomp('1.00001', '1', 3); // 0
echo bccomp('1.00001', '1', 5); // 1

但是,这些比较并未返回我期望的结果:

php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.3)  ); // Expect 0
0
php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.4)  ); // Expect 1
0
php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.2)  ); // Expect -1
0

确保,让我们确保strval()返回我们认为应该的内容:

php > echo strval(0.1+0.1+0.1);
0.3
php > echo strval(0.3);
0.3

为什么bccomp()在上面有问题的示例中返回0

1 个答案:

答案 0 :(得分:2)

您需要指定比例(bccomp()的第3个参数),如您在手册中引用的示例中所做的那样。我以17的比例尝试了它:

php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.3), 17 ); // Expect 0
0
php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.4), 17 ); // Expect -1
-1
php > echo bccomp(  strval(0.1+0.1+0.1), strval(0.2), 17 ); // Expect 1
1

这是正确的输出(你的期望是错误的 - 你有1和-1反转)。

我猜你想要做什么,你会调整比例以匹配你的delta(例如4)。但总的来说,我会小心使用bccomp()和'stringified'浮点结果。

编辑:如果你将精度设置得更高,例如ini_set('precision',17);,第一行的结果将会改变,反映出0.1 + 0.1 + 0.1大于0.3;你会得到1而不是0。