Мальчик, этот является действительно странным. Я ожидаю, что следующий код распечатает 1990, но он печатает 1989!
$val = '$19.9';
$val = preg_replace('/[^\d.]/','',$val);
$val = intval($val * 100);
echo $val;
С какой стати это происходит?
Править: и этот код:
$val = '$19.9';
$val = preg_replace('/[^\d.]/','',$val);
echo $val . "<br>";
$val = $val * 100;
echo $val . "<br>";
$val = intval($val);
echo $val;
Печать:
19.9
1990
1989
Почему делает intval(1990)
равный 1989
???
Это проблема точности, присущая числам с плавающей запятой в PHP и многих других языках. В этом отчете об ошибке это немного обсуждается в контексте преобразования типа int:
http://bugs.php.net/bug.php?id=33731
Попробуйте round ($ val * 100 )
вместо этого.
$ val
- это число с плавающей запятой - результат "19,9" * 100
. Числа с плавающей запятой не на 100% точны ни на одном языке (это сделано намеренно). Если вам нужна 100% -ная десятичная точность для долларовых значений, вы должны использовать целые числа и выполнять все вычисления с использованием центов (например, «19,90 долларов США»
должно быть 1990
).
Обычный ответ на такой вопрос - прочитать Что должен знать каждый компьютерный ученый об арифметике с плавающей запятой .
Почему intval(1990) равно 1989????
Потому что вы не берете intval(1990)
. Вы берете intval($val * 100)
, где $val
- число, близкое к 19.9, но немного меньшее его.
Прочитайте The Floating-Point Guide, чтобы понять, почему это так.
Что касается того, как это исправить: никогда не используйте значения с плавающей точкой для денег. В PHP вместо этого следует использовать BCMath.