我想知道我是否发现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);
答案 0 :(得分:7)
花车是邪恶的。
引用PHP manual documentation on Floating Point numbers:
因此,永远不要将浮点数结果信任到最后一位数,并且永远不要将浮点数与相等性进行比较。如果需要更高的精度,arbitrary precision math functions和gmp函数可用。
如果你想知道花车为什么以及如何工作,我建议观看:
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 ...”