例如......
$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
为什么区别于示例?缺乏精确度?
答案 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);