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!

Juan
  • 3,433
  • 29
  • 32
joshim5
  • 2,292
  • 4
  • 28
  • 40
  • i think this happens in any language, and its because the way floating point numbers are handled internally – Quamis Nov 21 '10 at 07:37

5 Answers5

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.

bcosca
  • 17,371
  • 5
  • 40
  • 51
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.

Matthew
  • 47,584
  • 11
  • 86
  • 98
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.

dkamins
  • 21,450
  • 7
  • 55
  • 59
  • also, its recommented you dont actually use floats for currency calculations, because of this loss of precision – Quamis Nov 21 '10 at 07:36
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.

icyrock.com
  • 27,952
  • 4
  • 66
  • 85
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.

cdhowie
  • 158,093
  • 24
  • 286
  • 300