2011-07-27 147 views
0

我期望所有下面的比较是bool(true),但它们不是。 任何人都可以解释这一点吗?PHP:浮点数学运算和比较

test.php的

<?php 

$f = 12; 
$f += 5.95; 
$f += 5.95; 
$f += 5.95; 

echo 'var_dump($f) = '; 
var_dump($f); 

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == '29.85'); 

echo 'var_dump($f == 29.85) = '; 
var_dump($f == 29.85); 

echo 'var_dump($f == (float)\'29.85\') = '; 
var_dump($f == (float)'29.85'); 

echo 'var_dump($f == \'29.85\') = '; 
var_dump((string)$f == '29.85'); 

echo 'var_dump(round($f, 2) == \'29.85\') = '; 
var_dump(round($f, 2) == '29.85'); 

$ PHP test.php的

var_dump($f) = float(29.85) 
var_dump($f == '29.85') = bool(false) 
var_dump($f == 29.85) = bool(false) 
var_dump($f == (float)'29.85') = bool(false) 
var_dump($f == '29.85') = bool(true) 
var_dump(round($f, 2) == '29.85') = bool(true) 

$ PHP -v

PHP 5.2.14 (cli) (built: Jul 23 2010 15:23:00) 
Copyright (c) 1997-2010 The PHP Group 
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies 
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans 
+2

的可能重复: http://stackoverflow.com/questions/3148937/compare-floats-in-php – DhruvPathak

回答

5

浮点数有精度的限制。虽然它取决于系统,但PHP通常使用IEEE 754双精度格式,即 ,由于以1.11e-16的顺序 进行四舍五入,因此它会给出最大相对误差。非基本算术运算可能会给出更大的错误,当然,当多个操作复合时,必须考虑错误编程。

此外,有理数是在基座10,如0.1或0.7精确表示作为 浮点数,没有一个 精确表示作为浮点数在基座2,其是 内部使用,不管尾数的大小。因此,他们 不能被转换成其内部的二进制对应,没有一个精度的小损失。这可能导致混乱的结果: 例如,地板((0.1 + 0.7)* 10)通常会返回7代替 预期8,由于内部表示将会像 7.9999999999999991118 ....

因此,不要将浮点数结果信任到最后一位,也不要将浮点数相等进行比较。

PHP documentation page

0

由于@Shakti辛格说,浮点数没有精确存储,所以我猜$ F实际存储为类似29.849999999999999 ......,所以不完全等于29.85 。

此外,该行代码如下错误:

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == 29.85); 

我认为它应该是:

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == '29.85'); 
+0

监督,我已经更新了,是的,结果仍是布尔的var_dump(假)($ F == '29 .85'); – kralos

1

当你比较值作为字符串,双方都'29.85',让您得到true。到目前为止这么容易。

通过数字值进行比较可将您引导到二进制浮点值表示法的土地。由于数字存储在base-2中,因此不是可以用表示有限的二进制扩展不能用精确地用浮点数表示。

换句话说,每个不能写成分母是2的幂的整数部分的数字都不能这样表示。这包括1/5和1/10和597/20(这是29.85)。

因为这些数字不能被精确表示,涉及到这样的数字运算的结果取决于操作的顺序和舍入和截断误差,因此例如.1 + .1 + .1并不像.3相同,并为您的计算类似。