我有以下的代码:
$a = 1.49;
$b = 1.50;
echo $b - $a; // Outputs 0.01, which is ok
if (($b - $a) != 0.01) {
echo "Not ok";
} else {
echo "Ok";
}
的问题是,如果声明回声“不好”,虽然减法结果是0.01。
任何想法为什么?
我有以下的代码:
$a = 1.49;
$b = 1.50;
echo $b - $a; // Outputs 0.01, which is ok
if (($b - $a) != 0.01) {
echo "Not ok";
} else {
echo "Ok";
}
的问题是,如果声明回声“不好”,虽然减法结果是0.01。
任何想法为什么?
这是因为一些浮点运算。结果不完全是0.01。系统会对您的输出进行四舍五入。
只是尝试var_dump(($b-$a)-0.01)
。这应该是float(8.673617379884E-18)
一个解决办法是if (round($b - $a,2) != 0.01)
的PHP doc on floating point numbers展示了如何比较他们
正如警告上面提到,对于 平等测试浮点值是有问题的,因为他们在内部代表 的方式。但是,有些方法可以针对这些限制进行浮点比较。
要测试相等的浮点值,使用由于舍入而导致的相对误差的上限。这个值被称为 机器的epsilon或单位舍入,并且是计算中最小的可接受的 。
<?php
// $a and $b are equal to 5 digits of precision.
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
?>
适用于你的例子:
$c = $b - $a;
$epsilon = 0.00001;
if (abs($a-$b-0.01) < $epsilon) {
echo "Not ok";
} else {
echo "Ok";
}
输出OK
我明白了,但比较必须双向工作,所以更小或更大。 – Psyche
[什么每台计算机科学家应该知道关于浮点运算(http://docs.oracle .com/cd/E19957-01/806-3568/ncg_goldberg.html) – Rapptz
@Rapptz虽然这通常是我会推迟的资源,但我不确定它适用于此。编辑:我错了。 –
@WaleedKhan无论如何,真正的浮点比较是非常棘手的。更不用说这个话题已经做了好几遍了。 – Rapptz