This article applies to **PHP 5.x** but also to **PHP 7**

While using **floating-point arithmetic** you might have noticed that not all the calculus results are as expected, this can usually be observed when casting values.

So the output for **(0.7 + 0.1) * 10** is:

var_dump((0.7+0.1)*10); # **float(8)**

var_dump(intval((0.7+0.1)*10)); # **int(7)**

Now let’s try it with 0.6 instead of 0.7

var_dump((0.6+0.1)*10); # **float(7)**

var_dump(intval((0.6+0.1)*10)); # **int(7)**

### How does the CPU understand these numbers?

The CPU makes the calculations binary, the floating point numbers are represented as follows:

IEEE Short Real: **32 bits** 1 bit for the sign, 8 bits for the exponent, and 23 bits for the mantissa. Also called single precision.

IEEE Long Real: **64 bits** 1 bit for the sign, 11 bits for the exponent, and 52 bits for the mantissa. Also called double precision.

The numbers that can easily be represented binary are: 1/(2^1). 1/(2^2) . 1/(2^3), 1/(2^4) etc. This because they have mantissa equal to 1 (enconded as 0).

The number values can only be represented exactly if they can be represented by this formula: **exponent** * **mantissa**

The **mantissa** is the number which the exponent is multiplied to. The mantissa value is **1 + 1/rb**, where **rb** is the reverse binary interpretation

Let’s take the number 3.5 for example.

The float numbers are **sign** * **exponent** * **mantissa. ** 3.5 = **1** * **2** * **1.75** .

**Mantissa: 1 + 11**000000000000000000000 -> 1/(2^0) + **1**/(2^1) + **1**/(2^2) + **0***(2^3) + … + **0***(2^23) -> 1 + 0.5 + 0.25 -> 1.75

Some numbers cannot be represented exactly (such as 0.99999999)

To learn more about how IEEE Real numbers are formed follow this link.

### Why does this happen?

Using this IEEE 754 converter we have found out that:

**0.7** is actually represented as **0.699999988079071**

**0.1** is actually represented as **0.10000000149011612**

If we add these two values we will obtain **0.7999999895691871**

And if we multiply it by 10 we obtain **7.999999895691871 **which if casted to int is **7** the same way** 3.5** is **3** if casted to int.

The other example still shows 7 because **0.6** is actually represented as **0.6000000238418579** and (0.6000000238418579 + 0.10000000149011612)*10 is **7,00000025331974
**

### But still …

If we use **echo** and **var_dump** or if applying mathematical operations, PHP automatically adjusts the values, but **intval** and casting to **int** work on their bits before the values were adjusted

var_dump((0.7+0.1)*10); # **float(8)**

var_dump(intval( **((0.7+0.1)*10) ** ) ); # **int(7)**

var_dump(intval( **((0.7+0.1)*10)+1** ) ); # **int(9)**

If these values are very important for your project you can get the correct values we by using the **BCMath PHP Extension**.

For a more technical & mathematical approach read this document.

## Leave a Reply