我通常通过比较浮点数差异的绝对值和任意小的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
?
答案 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。