Почему делает 'intval (19.9 * 100)', равняются '1989'?

Мальчик, этот является действительно странным. Я ожидаю, что следующий код распечатает 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???

11
задан Matt 12 May 2010 в 19:26
поделиться

4 ответа

Это проблема точности, присущая числам с плавающей запятой в PHP и многих других языках. В этом отчете об ошибке это немного обсуждается в контексте преобразования типа int:

http://bugs.php.net/bug.php?id=33731

Попробуйте round ($ val * 100 ) вместо этого.

17
ответ дан 3 December 2019 в 04:52
поделиться

$ val - это число с плавающей запятой - результат "19,9" * 100 . Числа с плавающей запятой не на 100% точны ни на одном языке (это сделано намеренно). Если вам нужна 100% -ная десятичная точность для долларовых значений, вы должны использовать целые числа и выполнять все вычисления с использованием центов (например, «19,90 долларов США» должно быть 1990 ).

0
ответ дан 3 December 2019 в 04:52
поделиться
3
ответ дан 3 December 2019 в 04:52
поделиться

Почему intval(1990) равно 1989????

Потому что вы не берете intval(1990). Вы берете intval($val * 100), где $val - число, близкое к 19.9, но немного меньшее его.

Прочитайте The Floating-Point Guide, чтобы понять, почему это так.

Что касается того, как это исправить: никогда не используйте значения с плавающей точкой для денег. В PHP вместо этого следует использовать BCMath.

2
ответ дан 3 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: