Я работаю над проектом для клиента, его довольно просто. Но есть один расчет, который я должен сделать, который также очень прост, как в этом примере:
$a = (49.95 - 24.95); if ($a == 25.00) { echo "TRUE"; }
Это равно 25.00! Но нет ли его возвращения ложным ???
Но если я это сделаю, еще один пример, похожий на расчет, который мне нужен:
$a = (99.95 - 24.95); if ($a == 75.00) { echo "TRUE"; }
Тогда я поправлюсь! Я сошел с ума, или это ошибка?
Как вы можете прочитать в руководстве, не сравнивайте float напрямую. Вместо этого используйте epsilon
.
<?php $a = 1.23456789; $b = 1.23456780; $epsilon = 0.00001; if(abs($a-$b) < $epsilon) { echo "true"; }
Это из-за того, как PHP хранит float внутри. Вы можете прочитать об этом в руководстве, например. здесь http://pl1.php.net/float
Это не ошибка. Речь идет о точности чисел с плавающей точкой . Поскольку числа с плавающей точкой сохраняются с десятичной точностью, вы не можете полагаться на операции точного сравнения, например ==
(сравнение равенства).
Вместо этого вы используете прецизионную дельта и сравниваете поплавки, например:
$a = (49.95 - 24.95); $b = 25; $delta = 1E-13; if(abs($a-$b)<$delta) { echo('TRUE'); }
В PHP 1E-13 будет достаточно для использования в качестве точности delta. Для очень простого объяснения см. Это руководство о числах с плавающей точкой и их представлении.
$a = (49.95 - 24.95); if ((int)$a == 25) { echo "TRUE"; }
В первом примере есть число с плавающей точкой, которое сравнивается с номером int, а во втором – число с плавающей точкой по сравнению с числом с плавающей точкой. Разница возникает из-за точности с плавающей запятой и ее не является ошибкой.
Чтобы решить эту проблему, вы можете определить число d (delta)
которое будет точностью вычисления
и тогда вы можете проверить, будет ли абсолютный результат xy
быть ниже заданной вами точности. Что-то вроде этого if(abs(xy) < d)