PHP舍入问题(5.2.3)?

时间:2010-02-02 19:57:51

标签: php rounding

我想知道我是否发现PHP中的舍入问题,特别是5.2.3(我目前不确定其他版本):

$t = 0;

$taxAmount = (5.000 / 100) * 0.7;
$t += $taxAmount;

var_dump($t); // float(0.035)
var_dump(round($t, 2)); // float(0.03)
var_dump(number_format($t, 2)); // string(4) "0.03"

对我来说0.035应该是0.04还是我只是疯了?

修改

感谢NebyGemini's answer,我想我会这样做:

$t = 0;

$taxAmount = bcmul(bcdiv(5.000, 100, 3), 0.7, 3);
$t += $taxAmount;

var_dump($t); // float(0.035)
var_dump(round($t, 2)); // float(0.04)
var_dump(number_format($t, 2)); // string(4) "0.04"

哪种方法很完美。

顺便说一句,我正在计算购物车中的税。订单总额为0.70(70美分),税率为5%。

修改

Thxs到Ignacio Vazquez-Abrams's answer,这是为了说明问题所在:

printf('%.18F', 5.000 / 100 * 0.7);

3 个答案:

答案 0 :(得分:7)

花车是邪恶的。

引用PHP manual documentation on Floating Point numbers

  

因此,永远不要将浮点数结果信任到最后一位数,并且永远不要将浮点数与相等性进行比较。如果需要更高的精度,arbitrary precision math functionsgmp函数可用。

如果你想知道花车为什么以及如何工作,我建议观看:
 Everything you didn't want to know about JavaScript numbers

答案 1 :(得分:3)

Python说:

>>> repr(5./100*0.7)
'0.034999999999999996'

这是由于IEEE754精度限制。如果您需要精确的准确度,请使用定点类型。

答案 2 :(得分:0)

您可以使用PHP_ROUND_HALF_UP,但是有一个问题,该数字会自动转换为“99999 ...”