With float, your assumption $x == $x + 1 not necessarily true:
$x=2; echo ((float)($x+1)==(float)($x))?'EQUAL':'Not Equal';
gives "Not equal."
In the converter linked in the comments ( http://www.h-schmidt.net/FloatConverter/IEEE754.html ), you can reproduce this. decimal 2.0 gives 0x40000000 , decimal 3.0 gives 0x40400000 , so they really differ from each other when it comes to the IEEE754 float representation.
While, for example, decimal 0.1 cannot be represented as float: 0x3dcccccd , which is equal to 0.10000000149011612 .
What is the decimal symbol 9223372036854775807 ? This is 0x5f000000 , which is 9.223372E18 , which is 9223372180000000000 .
What is the decimal symbol 9223372036854775808 ( PHP_MAX_INT + 1 )? This is also 0x5f000000 .
What is the decimal symbol 9223372036854776832 ( PHP_MAX_INT + 1025 )? This is also 0x5f000000 .
What is the decimal symbol 9223372036854776833 ( PHP_MAX_INT + 1026 )? This is also 0x5f000000 .
They are all the same.
Whereas, for example: decimal 9223373000000000000 ( PHP_MAX_INT + 963145224193 )? This is 0x5f000001 , which is 9.223373E18 , which is 9223373000000000000 .
Now why:
((float)($x+1025)==(float)($x+1026))?'EQUAL':'Not Equal';
Is Not Equal Exit?
You add an integer to PHP_MAX_INT .
$x=PHP_INT_MAX; $y=PHP_INT_MAX-1; $z=PHP_INT_MAX+1; var_dump($x); var_dump($y); var_dump($z);
gives:
int(9223372036854775807) int(9223372036854775806) float(9.2233720368548E+18)
PHP implicitly converts integers too large to float. And where you are mostly lost in PHP internals (at least in my opinion), because from here you will never know what will happen (without knowing the PHP internals, feel free to correct me).
Note:
$x=PHP_INT_MAX; $a=(float)($x+1025.0); // 1025 float $b=(float)($x+1026.0); // 1026 float $c=(float)($x+1025); // 1025 int $d=(float)($x+1026); // 1026 int var_dump($x); var_dump($a); var_dump($b); var_dump($c); var_dump($d); var_dump($a==$b); var_dump($a===$b); var_dump($c==$d); var_dump($c===$d);
gives:
int(9223372036854775807) float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) bool(true) bool(true) bool(false) bool(false)
If you add an integer ( $x+1026 ) to PHP_MAX_INT , it is converted to a float, and when you add a float ( $x+1026.0 ), it floats too. But, obviously, they are not internal, see Comparisons above.
Bottom line:
- Do not compare float for equality
- Be careful with your throws;
(float)($x+1026) is an integer addition and then casted to float, while (float)($x+1026.0) converts $x to float, then adds float 1026.0 , and then casts (unnecessarily) to float .
Edit: optional, see