Php 为什么我从两个假定相似的算术运算中得到不同的结果?
在下面的代码中,为什么乘法方法不会产生舍入错误,而累积加法会产生舍入错误Php 为什么我从两个假定相似的算术运算中得到不同的结果?,php,php-5.4,Php,Php 5.4,在下面的代码中,为什么乘法方法不会产生舍入错误,而累积加法会产生舍入错误 function get_value() { return 26.82; } function a($quantity) { $value_excluding_vat = get_value(); $value_including_vat = round($value_excluding_vat * (1 + (20 / 100)),2); $total_nett = 0; $total_
function get_value() { return 26.82; }
function a($quantity) {
$value_excluding_vat = get_value();
$value_including_vat = round($value_excluding_vat * (1 + (20 / 100)),2);
$total_nett = 0;
$total_gross = 0;
for($i=0; $i<$quantity; $i++) {
$total_nett += $value_excluding_vat;
$total_gross += $value_including_vat;
}
return array(
$total_nett,
$total_gross
);
}
function b($quantity) {
$value_excluding_vat = get_value();
$value_including_vat = round($value_excluding_vat * (1 + (20 / 100)),2);
return array(
$quantity * $value_excluding_vat,
$quantity * $value_including_vat
);
}
$totals = a(1000);
print_r($totals);
echo $totals[1] - $totals[0];
echo "\n\n";
$totals = b(1000);
print_r($totals);
echo $totals[1] - $totals[0];
问题可能存在(请参见警告块)
e、 g.21470.73可能是21470.729999..9994561或21470.73000…0001231,取决于它们是如何计算的
在计算
$total
之前,尝试对临时值进行四舍五入,例如gross\u total\u so\u far
和nett\u total\u so\u far
我猜不出浮点数表示和减法的问题,但是
在不进行四舍五入的情况下减去这些值,将得到结果**3578.455
当您将其四舍五入到小数点后两位时,它将以3578.46四舍五入
所以php有一个解决这个问题的方法
PHP_ROUND_HALF_UP Round val up to precision decimal places away from zero, when it is half way there. Making 1.5 into 2 and -1.5 into -2.
PHP_ROUND_HALF_DOWN Round val down to precision decimal places towards zero, when it is half way there. Making 1.5 into 1 and -1.5 into -1.
PHP_ROUND_HALF_EVEN Round val to precision decimal places towards the next even value.
PHP_ROUND_HALF_ODD Round val to precision decimal places towards the next odd value.
这些常数以四舍五入函数形式提供
echo round(100.675, 2, PHP_ROUND_HALF_UP); // 100.68
echo round(100.675, 2, PHP_ROUND_HALF_DOWN); // 100.67
S>强>PHPrOrth-LoopixLoad
>对于你的情况是有用的,首先,考虑在基10中有许多是有理数的,而不是二进制浮点表示中的数。例如,26.82的浮点值实际上是
26.8200000000000002842170943040400743484497
当然,如果您不断地将其添加到自身中,会出现一些错误,但最多可以添加15个有效数字-将其添加1000次,总数实际上是26819.9999997671693563461303710937500000000
有趣的问题是,当我们将26.82乘以1000.0时,我们得到的是26820.0000000000000000000000000000000000000000
——它是如何做到的
答案很简单,26820.0确实有一个精确的二进制表示,乘法运算足够聪明,可以发现这一点——即使乘以1001.0,减去26.82,仍然可以得到精确的答案
这里有几个有趣的链接
- -这使您可以查看浮点数的单精度表示,并有助于真正理解浮点数
- 这非常有趣,因为它涵盖了围绕舍入浮动的一些问题
- 及
echo round(100.675, 2, PHP_ROUND_HALF_UP); // 100.68
echo round(100.675, 2, PHP_ROUND_HALF_DOWN); // 100.67