1

遇到奇怪的问题:

$testTotal = 0;
foreach($completeBankArray as $bank){
   var_dump($testTotal);
   echo  " + ";
   var_dump(floatval($bank["amount"]));
   echo " = ".(floatval($testTotal) + floatval($bank["amount"]))."</br>";
   $testTotal = floatval(floatval($testTotal) + floatval($bank["amount"]));

这是我得到的输出:

------------------//--------------------
float(282486.09) + float(15) = 282501.09
float(282501.09) + float(3.49) = 282504.58
float(282504.58) + float(22.98) = 282527.55999999
float(282527.55999999) + float(5.2) = 282532.76
float(282532.76) + float(39.98) = 282572.73999999
float(282572.73999999) + float(2.6) = 282575.33999999
float(282575.33999999) + float(2.99) = 282578.32999999 
------------------//----------------------- 

这怎么可能,我在做什么?

4

4 回答 4

7

你没有做错什么。浮点数是出了名的不准确。来自文档(在巨大的红色警告框中):

浮点数的精度有限。尽管取决于系统,但 PHP 通常使用 IEEE 754 双精度格式,由于在 1.11e-16 的数量级四舍五入,这将给出最大的相对误差。非初等算术运算可能会产生更大的误差,当然,当多个运算复合时,必须考虑误差传播。

此外,可以精确表示为以 10 为底的浮点数的有理数,如 0.1 或 0.7,没有精确表示为以 2 为底的浮点数,无论尾数大小如何,它都在内部使用。因此,它们不能被转换成它们内部的二进制对应物,而不会有小的精度损失。这可能会导致令人困惑的结果:例如, floor((0.1+0.7)*10) 通常会返回 7 而不是预期的 8,因为内部表示将类似于 7.9999999999999991118...。

所以永远不要相信浮点数结果到最后一位,也不要直接比较浮点数是否相等。如果需要更高的精度,可以使用任意精度的数学函数gmp函数。

于 2012-09-05T23:20:31.743 回答
1

浮点数从来都不是精确的,从长远来看会存在很大差异。如果您正在使用精确数学,请阅读有关该bc 的信息。

于 2012-09-05T23:20:45.180 回答
0

经典数值精度示例。计算机以二进制形式存储浮点数。

简短的回答是计算机无法准确地以二进制表示某些浮点数。

长答案涉及在数字基础之间移动。如果你有一个浮点数,你不能完全用二进制表示它,除非分母包含可以分解为 2 的幂的因子。

于 2012-09-05T23:21:38.773 回答
0

其他答案已经让您深入了解为什么使用浮点数会出现这种行为。

如果您正在处理金钱,解决问题的一种方法是使用整数而不是浮点数,并使用美分而不是美元。然后你需要做的就是格式化你的输出以包含小数。

于 2012-09-05T23:57:09.343 回答