# PHP Gotcha II: When 1 plus 7 isn't 8

Look at this simple addition:

```
$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

Nice article about this topic is on wikipedia, but what about trying yourself? Here is tinny C program:

```
#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;
}
void print_bits(void *address, size_t size)
{
int i;
int b;
address += size-1;
printf("Printing %zu bytes:\n", size);
for (i = size-1; i >= 0; i--) {
for (b = 7; b >= 0; b--) {
printf("%d", (*(char *)address & (1<<b))>>b);
}
address--;
}
}
```

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 `01111111011`

is in decimal _{2}`1019`

, but we must subtract `1023`

so **exponent is -4**.

At the begging of fraction we put `1`

and we get a number

or **1**1001100110011001100110011001100110011001100110011010_{2}`7205759403792794`

in decimal format is fraction._{10}

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.79999999999999996114219413811952`^{1} 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

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