比较双精度的奇怪行为,两个PHP双精度值不相等

时间:2011-03-11 09:21:17

标签: php compare double

我在PHP中有两个看似相等的double值(至少在回显它们时)。

但是当将它们与double equals进行比较时,由于某种原因,它的计算结果为false。在进行这种比较时是否有任何特殊注意事项?

5 个答案:

答案 0 :(得分:9)

您不应使用==运算符比较浮点数。

查看大警告和explanation in the php manual

有什么可行的,就是声称这两个数字在彼此之间的某个小距离内是这样的:

if(abs($a - $b) < 0.0001) {
    print("a is mostly equal to b");
}

原因是由于在将小数转换为二进制后执行的浮点运算导致的舍入误差,然后转换回十进制。这些来回转换会导致0.1 + 0.2不等于0.3的现象。

答案 1 :(得分:1)

不应该对float和double进行相等性比较:有一些精确错误会使两个数字看起来不同,即使它们看起来相同(当它们被打印出来时,它们通常是圆形的)。

比较的正确方法是使用一些DELTA常量:

define(DELTA, 0.00001); // Or whatever precision you require

if (abs($a-$b) < DELTA) {
  // ...
}

另请注意,这不是PHP特定的,但在其他语言(Java,C,...)

中也很重要

答案 2 :(得分:1)

PHP(as well as in C and many other languages)中浮点数的表示是不精确的。由于这个事实,看似相同的数字实际上可能是不同的,并且比较将失败。相反,选择一些小数字并检查差异是否小于,<:p>

if(abs($a-$b)<0.00001) {
  echo "Equal!";
}

另见explanations in the PHP manual

答案 3 :(得分:1)

我做的一个小功能,希望帮助某人:

function are_doubles_equal($double_1, $double_2, $decimal_count) {
    if (!$decimal_count || $decimal_count < 0) {
        return intval($double_1) == intval($double_2);
    }
    else {
        $num_1 = (string) number_format($double_1, $decimal_count);
        $num_2 = (string) number_format($double_2, $decimal_count);
        return $num_1 == $num_2;
    }
}

用法:

$a = 2.2;
$b = 0.3 + 1.9002;

are_doubles_equal($a, $b, 1); // true : 2.2 == 2.2 
are_doubles_equal($a, $b, 1); // false : 2.2000 == 2.2002

答案 4 :(得分:0)

不是最快的方法,而是在比较之前转换为字符串:

if( strval($a) === strval($b) ){
  // double values are exactly equal
}