Matok's PHP Blog

# PHP Gotcha II: When 1 plus 7 isn't 8 ``````\$a = 0.1;
\$b = 0.7;

if (\$a + \$b == 0.8) {
echo '0.1 + 0.7 is 0.8';
} else {
echo '0.1 + 0.7 is NOT 0.8';
}
``````

The result is: 0.1 + 0.7 is NOT 0.8 Actually, this is not matter of PHP. This is how floating point arithmetic works.

## How real numbers are stored?

You can find big red warning on manual page. Important is this information:

PHP typically uses the IEEE 754 double precision format

``````#include <stdio.h>
#include <stdlib.h>

void print_bits(void *a, size_t size);

int main()
{
double number;

printf("Gimme float number: ");
scanf("%lf", &number);
printf("\n");

print_bits(&number, sizeof(number));
printf("\n");

return EXIT_SUCCESS;
}

{
int i;
int b;

printf("Printing %zu bytes:\n", size);
for (i = size-1; i >= 0; i--) {
for (b = 7; b >= 0; b--) {
}

}
}
``````

You can download it from GitHub. When I enter number `0.1` on input I got this output:

0011111110111001100110011001100110011001100110011001100110011010

According to wikipedia article:

First `0` is sign and this means positive number. Next 11 bits `01111111011` is exponent. Rest of this number `001100110011001100110011001100110011001100110011010` is fraction.

Exponent `011111110112` is in decimal `1019`, but we must subtract `1023` so exponent is -4.

At the begging of fraction we put `1` and we get a number `110011001100110011001100110011001100110011001100110102` or ‭`720575940379279410` in decimal format is fraction.

Equation to concrete real number is:
2-4 * (7205759403792794 * 2-52)
2-56 * 7205759403792794

0.10000000000000000555111512312578 = `0.1`

0.69999999999999995559107901499374 = `0.7` (computed by same principles)

## Conclusion

When I add this two numbers I get 0.799999999999999961142194138119521 and that is really close to 0.8 but it isn't exactly equal. This is how real numbers are stores in computer memory no matter of programming language you are using.

If you are working with float you must consider this behavior, avoid using `==` or `===` with real numbers. You are safe if you do sum in MySQL on decimal type or use some kind of math library which can handle this float precision issue.

Footnotes:

1: All calculations were made by calculator, some last significant may be stripped - but it isn't important

If you like this article then mark it as helpful to let others know it's worth to read. Otherwise leave me a feedback/comment and we can talk about it.

I'm foreigner. Where I live my friends call me Maťok.