PHP integer rounding problems

后端 未结 5 1101
-上瘾入骨i
-上瘾入骨i 2021-01-13 08:31

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

相关标签:
5条回答
  • 2021-01-13 08:47

    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.

    0 讨论(0)
  • 2021-01-13 08:50

    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.

    0 讨论(0)
  • 2021-01-13 08:57

    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.

    0 讨论(0)
  • 2021-01-13 08:59

    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:

    • http://en.wikipedia.org/wiki/Binary_numeral_system

    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.

    0 讨论(0)
  • 2021-01-13 08:59

    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.

    0 讨论(0)
提交回复
热议问题