PHP:浮点数学和比较
我希望下面所有的比较都是布尔(真实的),但事实并非如此。 有人能解释一下吗 test.php $php-vPHP:浮点数学和比较,php,casting,comparison,Php,Casting,Comparison,我希望下面所有的比较都是布尔(真实的),但事实并非如此。 有人能解释一下吗 test.php $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,
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
浮点数的精度有限。尽管这取决于
PHP系统通常使用IEEE 754双精度格式,
由于顺序的四舍五入,这将给出最大的相对误差
第1.11e-16节。非初等算术运算可能会产生更大的错误
错误,当然,当发生错误时,必须考虑错误预测
一些行动是复杂的
另外,有理数可以精确表示为
以10为基数的浮点数,如0.1或0.7,没有
精确表示为基数2中的浮点数,即
在内部使用,无论尾数的大小。因此,他们
如果没有
精度损失小。这可能会导致令人困惑的结果:例如
例如,楼板((0.1+0.7)*10)通常返回7,而不是
预期为8,因为内部表示类似于
7.9999999999999118
所以永远不要相信最后一位的浮点数结果,也永远不要相信
比较浮点数是否相等
浮点数的精度有限。尽管这取决于
PHP系统通常使用IEEE 754双精度格式,
由于顺序的四舍五入,这将给出最大的相对误差
第1.11e-16节。非初等算术运算可能会产生更大的错误
错误,当然,当发生错误时,必须考虑错误预测
一些行动是复杂的
另外,有理数可以精确表示为
以10为基数的浮点数,如0.1或0.7,没有
精确表示为基数2中的浮点数,即
在内部使用,无论尾数的大小。因此,他们
如果没有
精度损失小。这可能会导致令人困惑的结果:例如
例如,楼板((0.1+0.7)*10)通常返回7,而不是
预期为8,因为内部表示类似于
7.9999999999999118
所以永远不要相信最后一位的浮点数结果,也永远不要相信
比较浮点数是否相等
正如@Shakti Singh所说,浮点数不是精确存储的,所以我猜$f实际上存储为类似29.84999999999…,所以不完全等于29.85 此外,此代码行看起来是错误的:
echo 'var_dump($f == \'29.85\') = ';
var_dump($f == 29.85);
我想应该是:
echo 'var_dump($f == \'29.85\') = ';
var_dump($f == '29.85');
正如@Shakti Singh所说,浮点数不是精确存储的,所以我猜$f实际上存储为类似29.849999999999的东西,所以不完全等于29.85 此外,此代码行看起来是错误的:
echo 'var_dump($f == \'29.85\') = ';
var_dump($f == 29.85);
我想应该是:
echo 'var_dump($f == \'29.85\') = ';
var_dump($f == '29.85');
当您将值作为字符串进行比较时,两边都是
'29.85'
,因此得到true
。到目前为止很容易
通过数值进行比较,您将进入二进制浮点值表示的领域。由于数字是以2为基数存储的,任何在有限二进制展开中无法表示的实数都不能用浮点数精确表示
换言之,如果分母是2的幂,那么不能写成整数分数的每个数字就不能这样表示。这包括1/5、1/10和597/20(即29.85)
由于这些数字无法精确表示,因此涉及这些数字的运算结果取决于运算顺序以及舍入和截断错误,因此,例如
.1+.1+.1
与.3
不同,并且在计算中类似。将值作为字符串进行比较时,两边都是'29.85'
,因此您可以得到true
。到目前为止很容易
通过数值进行比较,您将进入二进制浮点值表示的领域。由于数字是以2为基数存储的,任何在有限二进制展开中无法表示的实数都不能用浮点数精确表示
换言之,如果分母是2的幂,那么不能写成整数分数的每个数字就不能这样表示。这包括1/5、1/10和597/20(即29.85)
由于这些数字无法精确表示,涉及这些数字的运算结果取决于运算顺序以及舍入和截断错误,因此,例如
.1+.1+.1
与.3
不同,与您的计算类似。可能重复:可能重复:疏忽,我已更新,是的,var_dump($f=='29.85')的结果仍然是bool(false);疏忽,我已经更新了,是的,var_dump的结果仍然是bool(false)($f=='29.85');