5

echo (int) ( (0.1+0.7) * 10 );

Why does the above output 7? I understand how PHP rounds towards 0, but isn't (0.1+0.7) * 10 evaluated as a float and then casted as an integer?

Thanks!

1
  • i think this happens in any language, and its because the way floating point numbers are handled internally Commented Nov 21, 2010 at 7:37

5 Answers 5

7

There's a loss in precision when decimals are converted internally to their binary equivalent. The computed value will be something like 7.9+ instead of the expected 8.

If you need a high degree of accuracy, use the GMP family of functions or the bcmath library.

Sign up to request clarification or add additional context in comments.

Comments

2

See the manual:

http://php.net/manual/en/language.types.float.php

It is typical that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9.

Comments

1

The other answers explained WHY this happens. This should get you what you want:

echo (int) round( (0.1+0.7) * 10 );

Just round the float before casting it to an int.

1 Comment

also, its recommented you dont actually use floats for currency calculations, because of this loss of precision
0

I don't have php installed, but in python:

$ python
>>> 0.1+0.7
0.79999999999999993
>>> 

Not all numbers in base 10 can be represented precisely in base 2 system. Check Wikipedia article:

section Fractions in Binary. In particular, this line:

Fraction    Decimal     Binary  Fractional Approx.
1/10    0.1     0.000110011...  1/16+1/32+1/256...

1/10 cannot be represented in a finite way in base 2. Thus, 0.1 + 0.7 cannot be precisely calculated in base 2.

Never assume floating-point calculations are precise, it will bite you sooner or later.

Comments

0

1/10 cannot be represented in a finite number of binary digits, just like 1/3 cannot be represented as a finite number of base-10 digits. Therefore you are actually adding together 0.09999999999999... and 0.69999999999999... -- the sum is almost 8, but not quite.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.