比较浮点数-相同的数字,但不相等


Comparing floats - same number, but does not equal?

我有两个变量,$_REQUEST['amount']$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计算以确保它们被处理为浮点数,而不是字符串之后)。

I got this back:

float(168.57)
float(168.57)

非常非常令人沮丧。是什么原因造成的呢?

浮点数具有有限的精度。在这里查看关于比较它们的警告:

http://php.net/manual/en/language.types.float.php

浮点数不是100%准确的!你在PHP中计算可能会返回10.00000000001,它不等于10。

使用sprintf (http://php.net/manual/en/function.sprintf.php)对浮动进行格式化,然后再进行比较。

使用number_format代替乘1。

 $carttotal = number_format((int)$carttotal,2,'.','');
 $_REQUEST['amount'] = number_format((int)$_REQUEST['amount'],2,'.','');