Press "Enter" to skip to content

An Answer to a Common PHP Floating-Point Question

I previously wrote an article about PHP floating-point numbers: All 'bogus' about the float in PHP.
However, I missed one point at the time — the answer to this common question:

<?php
    $f = 0.58;
    var_dump(intval($f * 100)); // why does it output 57?
?>

Why does it output 57? Is it a PHP bug?
I believe many of you have had this same question, since lots of people have asked me similar things, not to mention the frequent questions on bugs.php.net...
To understand the reason, we first need to know how floating-point numbers are represented (IEEE 754):
A floating-point number, taking the 64-bit length (double precision) as an example, is represented with 1 sign bit (E), 11 exponent bits (Q), and 52 mantissa bits (M) (64 bits in total).
Sign bit: the highest bit indicates the sign of the number, 0 for positive, 1 for negative.
Exponent: represents the power of base 2, encoded with a biased exponent.
Mantissa: represents the significant digits after the binary point.
The key point here is the binary representation of fractions. As for how to represent a fraction in binary, you can do a web search yourself; I won't elaborate here. What we really need to understand is that 0.58, in binary, is an infinitely long value (the numbers below omit the implicit 1)...

The binary representation of 0.58, essentially (52 bits), is: 0010100011110101110000101000111101011100001010001111
The binary representation of 0.57, essentially (52 bits), is: 0010001111010111000010100011110101110000101000111101

And the two, computed with just these 52 bits, come out to respectively:

0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995

As for the exact floating-point multiplication details of 0.58 * 100, we won't go into that much detail; those interested can read (Floating point). Let's just estimate it in our heads... 0.58 * 100 = 57.999999999
So intval-ing it naturally gives you 57...
You can see that the crux of this problem is: "A fraction that looks finite to you is actually infinite in the computer's binary representation"
So, please stop thinking of this as a PHP bug — that's just how it is....

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.