Неверные результаты, полученные в простой арифметике с использованием php
Вот простой PHP-скрипт:
<?php
$a = 100;
$b = 91.51;
$c = 8.49;
$d = $a - $b - $c;
echo $d;
?>
Он выводит -5.3290705182008E-15, что уродливо С незначительными изменениями следующим образом:
$d = $a - ($b + $c);
echo $d;
?>
Вывод равен 0, что является правильным. Почему это происходит?
2 answers
Попробуйте использовать числовой формат следующим образом:
$a = 100;
$b = number_format(91.51, 0, ".", "." );
$c = number_format(8.49, 0, ".", "." );
$d = $a - $b - $c;
echo $d;
Математика с плавающей запятой на самом деле очень неточна. Это значение "наилучшего предположения";)
С плавающей запятой (одинарная точность) 100 - 91.51 - это не 8.49, как можно было бы ожидать, а 8.4899978638, поскольку значение 8.49 не может быть точно выражено в плавающей запятой. С двойной точностью он становится лучше, так как он равен 8,48999999999999488409, что немного ближе. Хотя все еще не совсем точно.
Возьмем следующий пример кода:
echo (100 - 91.51) . "\n";
echo number_format(100 - 91.51, 20) . "\n";
Результат, которого вы ожидали бы быть
8.49
8.49000000000000000000
Но на самом деле это так:
8.49
8.48999999999999488409
По умолчанию для печати значений с плавающей запятой используется округление до 2 знаков после запятой.
Плавающая точка - это в значительной степени компромисс. Это система числового представления, которая обеспечивает повышенное разрешение и дальность действия за счет точности. Для точности, но с ограниченным разрешением и диапазоном часто используется арифметика с фиксированной точкой. Например, если вы сохраняли значения напряжения от 0 В до 5 В и хотели получить точные измерения с разрешением 1 мкВ (т. Е. деления 0,000001В) вы можете вместо этого представить свои напряжения в микровольтах, а не в вольтах, поэтому значение 100000 на самом деле будет равно 0,1 В, а 3827498 будет 3,827498 вольт. Математика с заданным вами разрешением становится точной, однако у вас нет возможности представить 287x1036 V без наличия массивных переменных для хранения значения.