I’m using PHP 8.1 and I have something like this:
$same = ((int) (5.02 / 0.01) === 502);
Out of no where the $same
is false
.
I have printed the result of 5.02 / 0.01
and it returns 502.0
.
After some struggling with PHP, I managed to solve my problem using by an odd way:
$same = ((int) (5.02 / 0.01).'') === 502;
The question is why I need to concat the result with an empty string to get what I excpected?
The funny part is echo (int) (5.02 / 0.01);
returns 501
!!!!!
2
Answers
This looks like floating point vagaries. I did a bit of digging:
If you add a very tiny amount, you can make it tip over:
This isn’t particularly satisfying, I’ll grant, but probably the cleanest way to do it is to round rather than cast straight to int. Your workaround is effective (at least in this case) because it forces PHP to treat the result as a string instead of a float, which
(int)
then casts quite easily:See here for more info. Note this is why generally for values where accuracy matters, such as currency, it is recommended to use integers.
For example, if you are dealing in pounds/pence (or dollars/cents), you would store and evaluate all calculations in pence (or cents) and then divide by 100 at the last minute when you display the result.
This is nothing new and is due how floating point numbers are represented in binary form. The tl;dr is a computer only has finite precision to represent (any number really) numbers.
This is also why
0.1 + 0.2 === 0.3
is false in JavaScript (I don’t know if this is the case in other languages) for example.