Возможный дубликат:
Как мне сделать сравнение с плавающей запятой?
Сопоставление php integer и float
У меня есть две переменные: $_REQUEST['amount']
и $carttotal
, что $carttotal
электронной коммерции. Разумеется, они должны совпадать при попытке обработать платеж, чтобы предотвратить ручную отмену суммы платежа в последнюю минуту или, конечно, ошибку расчета.
Однако:
$carttotal = $carttotal * 1; $_REQUEST['amount'] = $_REQUEST['amount'] * 1; if($carttotal != $_REQUEST['amount']) { $code = 0; // cart empty under this user - cannot process payment!!! $message = 'The cart total of ' . $carttotal . ' does not match ' . $_REQUEST['amount'] . '. Cannot process payment.'; $amount = $carttotal; $json = array('code' => $code, 'message' => $message, 'amount' => $amount); die(json_encode($json)); } else { $trnOrderNumber = $client->id . '-' . $carttotal; }
Вышеприведенный код, с теми же номерами, не дает мне равных. В основном я получаю сообщение об ошибке, как будто $carttotal != $_REQUEST['amount']
true
(неравные вары).
Поэтому, чтобы проверить вары, я проскользнул:
var_dump($_REQUEST['amount']); var_dump($carttotal);
Чтобы узнать, что происходит (после выполнения * 1
вычислений, чтобы убедиться, что они рассматриваются как поплавки, а не строки).
Я получил это обратно:
float(168.57) float(168.57)
Очень очень расстраивает. Что может быть причиной этого?
числа с плавающей запятой имеют ограниченную точность. просмотрите предупреждение о сравнении их здесь:
Числа с плавающей точкой НЕ ТОЧНО! Вы вычисляете в PHP, может возвращать 10.00000000001, который НЕ равен 10.
Используйте sprintf ( http://php.net/manual/en/function.sprintf.php ), чтобы форматировать поплавки, прежде чем сравнивать их.
Вместо умножения на один используйте number_format.
$carttotal = number_format((int)$carttotal,2,'.',''); $_REQUEST['amount'] = number_format((int)$_REQUEST['amount'],2,'.','');