Почему это значение, полученное из floatval (), оценивается как ложное при сравнении с другим числом? - PullRequest
2 голосов
/ 22 марта 2011

Смотрите тестовый пример ниже:

$val = floatval("336.00");
$result = 300*1.12;

header("content-type: text/plain");

echo "\$result = 300*1.12 which equals $result\n";
echo "\$val = floatval(\"336.00\") which equals $val\n";
echo "gettype(\$val) = ".gettype($val)."\n";
echo "gettype(\$result) = ".gettype($result)."\n";
echo "gettype(300*1.12) = ".gettype(300*1.12)."\n";
echo "gettype(floatval(\$result)) = ".gettype(floatval($result))."\n";

if ($result == 300*1.12) 
    echo "\$result == 300*1.12 is true\n";
else
    echo "\$result == 300*1.12 is false\n";

if ($result == $val) 
    echo "(\$result == \$val) \$result == 300*1.12 is true\n";
else
    echo "(\$result == \$val) \$result == 300*1.12 is false\n";

Вы думаете, что последний блок if / else также будет показывать true, верно?Не так!Смотрите вывод из того же сценария:

$result = 300*1.12 which equals 336
$val = floatval("336.00") which equals 336
gettype($val) = double
gettype($result) = double
gettype(300*1.12) = double
gettype(floatval($result)) = double
$result == 300*1.12 is true
($result == $val) $result == 300*1.12 is false

Что мне здесь не хватает?Я пробовал это на разных версиях PHP 5+, и все они выдают одинаковый вывод.

Ответы [ 2 ]

6 голосов
/ 22 марта 2011
1 голос
/ 22 марта 2011

Если вы прочтете немного об арифметике с плавающей точкой, вы увидите, что во время каждой операции часто допускается небольшая ошибка. Это означает, что вы не можете сравнить два значения с плавающей точкой на равенство

$a == $b;

Однако вы можете проверить, достаточно ли мала ошибка для определенной точности:

abs($a - $b) < $eps;

$eps зависит от системы, которую вы используете, вы можете узнать больше об этом на Wiki . Конечно, это относится только к одной арифметической операции. После выполнения нескольких операций вам необходимо соответствующим образом масштабировать эпсилон.

...