Odd behavior comparing doubles, two double PHP values ​​are not equivalent

I have two seemingly equal double values ​​in PHP (at least when their echo repeats them).

But comparing them with double equals, for some reason it calculates false. Are there any special considerations when making such a comparison?

+4
source share
4 answers

You cannot compare floating point numbers using the == operator.

See the big warning and explanation in the php manual

What will work by claiming that two numbers are at some small distance from each other, like this:

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

The reason is due to rounding errors due to floating point arithmetic performed after decimal numbers are converted to binary and then converted back to decimal. These back and forth transformations cause a phenomenon in which 0.1 + 0.2 not equal to 0.3 .

+9
source

The representation of floating point numbers in PHP ( as well as in C and many other languages ) is inaccurate. Because of this, it would seem that equal numbers may be different, and the comparison will not work. Instead, select a small number and verify that the difference is less than:

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

See also the explanations in the PHP manual .

+1
source

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

The correct way to compare is to use the DELTA constant:

 define(DELTA, 0.00001); // Or whatever precision you require if (abs($a-$b) < DELTA) { // ... } 

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

0
source

The little function that I did, hopefully helps someone:

 function isDoubleEqueal($num1, $num2, $decimalCnt){ if(!$decimalCnt || $decimalCnt < 0) return intval($num1) == intval($num2) ; $num1 = (string) number_format($num1, $decimalCnt); $num2 = (string) number_format($num2, $decimalCnt); return $num1 == $num2 ;} 

Using:

  $a = 2.2; $b = 0.3 + 1.9002; isDoubleEqueal($a, $b, 1)// true : 2.2 == 2.2 isDoubleEqueal($a, $b, 1)// false : 2.2000 == 2.2002 
0
source

Source: https://habr.com/ru/post/1343296/


All Articles