PHP. result of the subtraction of two floating point numbers

10 浏览
0 Comments

PHP. result of the subtraction of two floating point numbers

例如...\n

$aa = 10694994.89;
$bb = 10696193.86;
$ab = $aa - $bb;
// 结果为:-1198.9699999988 而不是 -1198.97

\n但在这个例子中:\n

$cc = 0.89;
$dd = 0.86;
$cd = $cc - $dd;
// 结果为:0.03

\n为什么两个例子的结果不同?缺乏精度吗?

0
0 Comments

这是因为计算机在处理浮点数时会出现精度问题。浮点数是通过二进制来表示的,但二进制无法精确表示某些小数,因此会导致计算结果不准确。

解决方法是使用round函数对计算结果进行四舍五入,以保留指定的小数位数。在上述示例中,使用round函数将计算结果保留两位小数。

以下是完整的代码示例:

$aa = 10694994.89;
$bb = 10696193.86;
echo $ab = round($aa - $bb, 2);

通过对计算结果进行四舍五入,可以得到正确的结果。

0
0 Comments

PHP浮点数的减法结果问题的原因在于浮点数在二进制中无法精确表达。它们都经过某种方式的四舍五入。问题在于为什么其中一个结果似乎被四舍五入到了两位小数,而另一个没有。答案在于浮点数的精度和准确度以及PHP用于打印它们的精度之间的差异。

浮点数由范围为[1, 2)的尾数(或称为有效数字)表示,通过乘以2的幂进行缩放(这就是浮点数中的“浮点”意味着什么)。数字的精度取决于尾数中的数字位数,而准确度取决于其中多少位实际上是正确的。

当在PHP中使用echo打印浮点数时,它们首先会使用precision配置设置进行转换为字符串,该设置默认为14。要了解实际情况,必须使用更大的精度打印数字。

下面的代码示例展示了实际发生的情况:

$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位精度打印时几乎不会被注意到。

0