Проблемы с округлением целочисленного числа в PHP

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

Почему приведенный выше вывод 7? Я понимаю, как PHP округляется к 0, но не (0.1+0.7) * 10 оценивается как float и затем отливается как целое число?

Благодаря!

Solutions Collecting From Web of "Проблемы с округлением целочисленного числа в PHP"

Есть потеря точности, когда десятичные числа преобразуются внутренне в их двоичный эквивалент. Вычисленное значение будет чем-то вроде 7.9+ вместо ожидаемого 8.

Если вам нужна высокая степень точности, используйте семейство функций GMP или библиотеку bcmath .

См. Руководство:

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

Типично, что простые десятичные дроби, такие как 0,1 или 0,7, не могут быть преобразованы в их внутренние двоичные копии без небольшой потери точности. Это может привести к запутывающим результатам: например, пол ((0,1 + 0,7) * 10) обычно возвращает 7 вместо ожидаемого 8, так как внутреннее представление будет чем-то вроде 7.9.

Другие ответы объяснили, почему это происходит. Это должно получить то, что вы хотите:

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

Просто вокруг float перед тем, как передать его в int.

У меня нет php, но в python:

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

Не все числа в базе 10 могут быть представлены точно в системе основания 2. Проверить статью в Википедии:

раздел Фракции в двоичном формате. В частности, эта строка:

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

1/10 не может быть представлено конечным образом в основании 2. Таким образом, 0.1 + 0.7 не может быть точно рассчитан в базе 2.

Никогда не предполагайте, что вычисления с плавающей запятой точны, они рано или поздно укусят вас.

1/10 не может быть представлено в конечном числе двоичных цифр, так же как 1/3 не может быть представлено как конечное число базовых 10 цифр. Поэтому вы фактически суммируете 0.09999999999999 … и 0.69999999999999 … – сумма почти 8, но не совсем.