PHP。减去两个浮点数的结果

时间:2014-11-18 21:52:48

标签: php floating-point-precision subtraction

例如......

$aa = 10694994.89;
$bb = 10696193.86;
$ab = $aa - $bb;
// result is:-1198.9699999988 not the -1198,97

但是在这个例子中:

$cc = 0.89;
$dd = 0.86;
$cd = $cc - $dd;
//Result is: 0.03

为什么区别于示例?缺乏精确度?

2 个答案:

答案 0 :(得分:3)

您的代码中的数字都不能以二进制浮点表示完全。它们都以某种方式被舍入。问题是为什么其中一个结果(看似)四舍五入到两位小数而不是另一个。答案在于浮点数的精度精度之间的差异以及PHP用于打印它们的精度。

浮点数由{em>有效数(或尾数)表示,范围为[1, 2),通过将其乘以2的幂来进行缩放。 (这就是浮点“漂浮”的意思)。数字的精度有效数字中的位数决定。 准确度取决于这些数字中有多少实际上是正确的。有关详细信息,请参阅:How are floating point numbers are stored in memory?

当您在PHP中使用echo浮点数时,它们首先使用precision配置设置转换为字符串,默认为14.(在Zend/zend_operators.c中)

要查看实际情况,您必须使用更高的精度打印数字:

$aa = 10694994.89;
$bb = 10696193.86;
$ab = $aa - $bb;

printf ("\$aa: %.20G\n", $aa);
printf ("\$bb: %.20G\n", $bb);
printf ("\$ab: %.20G\n\n", $ab);

$cc = 0.89;
$dd = 0.86;
$cd = $cc - $dd;

printf ("\$cc: %.20G\n", $cc);
printf ("\$dd: %.20G\n", $dd);
printf ("\$cd: %.20G\n", $cd);

<强>输出:

$aa: 10694994.890000000596
$bb: 10696193.859999999404
$ab: -1198.9699999988079071

$cc: 0.89000000000000001332
$dd: 0.85999999999999998668
$cd: 0.030000000000000026645

初始数字的精度约为16到17位。当你减去$aa-$bb时,前4位数相互抵消。结果(虽然仍然具有大约16到17位数的精度),现在仅准确到大约12位数。当使用14位精度打印结果时,会显示较低的精度。

另一个减法($cc-$dd)仅丢失一位数的精度,当以14位精度打印时,这是不明显的。

答案 1 :(得分:1)

这应该适合你:

(你必须围绕你的结果!)

$aa = 10694994.89;
$bb = 10696193.86;
echo $ab = round($aa - $bb, 2);
相关问题