Odd behavior comparing doubles, two PHP double values aren't equivalent

你说的曾经没有我的故事 提交于 2020-05-13 04:36:05

问题


I have two seemingly equal double values in PHP (at least when echoing them).

But when comparing them with double equals, for some reason, it evaluates to false. Are there any special considerations when performing this kind of comparison?


回答1:


You shouldn't compare floating point numbers using the == operator.

See the big warning and explanation in the php manual

What will work is asserting that the two numbers are within a certain small distance of each other like this:

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

The reason is because of rounding errors due to floating point arithmetic performed after the decimals are converted to binary, then converted back to decimal. These back and forth conversions cause the phenomenon where 0.1 + 0.2 does not equal 0.3.




回答2:


float and double should never be compared for equality: there are precision errors that will make two numbers different even if they seem equal (when they are printed out, they are usually rounded).

Proper way to compare is using some DELTA constant:

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

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

Also note that this is not PHP specific but also important in other languages (Java, C, ...)




回答3:


Representation of floating point numbers in PHP (as well as in C and many other languages) is inexact. Due to this fact, seemingly equal numbers can in fact be different and comparison will fail. Instead, choose some small number and check that the difference is less than that, like:

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

See also explanations in the PHP manual.




回答4:


A small function i made, hope helps someone:

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;
    }
}

Usage:

$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



回答5:


Not the fastest way but convert to string before comparing:

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


来源:https://stackoverflow.com/questions/5271058/odd-behavior-comparing-doubles-two-php-double-values-arent-equivalent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!