问题
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