-2

一方面,我理解 Perl 的浮点数是不精确的二进制表示,这导致 Perl 的数学有时是错误的。我不明白的是,为什么有时这些花车似乎给出了准确的答案,而其他时候却没有。 是否可以预测 Perl 的浮点数学何时会给出错误(即不准确的答案)?

例如,在下面的代码中,当减法为“16.12 - 15.13”时,Perl 的数学错误 1 ​​次,当问题为“26.12 - 25.13”时错误 2 次,当问题为“36.12 - 35.13”时错误 20 次. 此外,出于某种原因,在所有上述测试用例中,我们的减法问题(即 $subtraction_problem)的结果一开始是错误的,但随着我们从中添加或减去的越多(使用$x)。这是没有意义的,为什么我们在算术问题中添加或减去的越多,值就越有可能是正确的(即精确的)?

my $subtraction_problem = 16.12 - 15.13;
my $perl_math_failures = 0;
for (my $x = -25; $x< 25; $x++){
        my $result = $subtraction_problem +$x;
        print "$result\n";
        $perl_math_failures++ if length $result > 6;
}
print "There were $perl_math_failures perl math failures!\n";
4

1 回答 1

5

这些都不是 Perl 特有的。见戈德堡

舍入误差

将无限多个实数压缩为有限位数需要近似表示。尽管整数有无限多,但在大多数程序中,整数计算的结果可以存储在 32 位中。相反,给定任何固定位数,大多数实数计算将产生无法使用那么多位精确表示的量。因此,浮点计算的结果必须经常四舍五入以适应其有限表示。这种舍入误差是浮点计算的特征。相对误差和 Ulps 部分描述了它是如何测量的。

由于大多数浮点计算无论如何都有舍入误差,如果基本算术运算引入了比必要更多的舍入误差,这有关系吗?这个问题是贯穿本节的一个主题。Guard Digits 部分讨论了保护数字,这是一种在减去两个相邻数字时减少错误的方法。IBM 认为保护数字非常重要,因此在 1968 年它在 System/360 架构中的双精度格式中添加了一个保护数字(单精度已经有一个保护数字),并改装了该领域的所有现有机器。给出了两个例子来说明保护数字的效用。

IEEE 标准不仅仅要求使用保护数字。它给出了加法、减法、乘法、除法和平方根的算法,并要求实现产生与该算法相同的结果。因此,当一个程序从一台机器移动到另一台机器时,如果两台机器都支持 IEEE 标准,则基本操作的结果在每一位都是相同的。这大大简化了程序的移植。此精确规范的其他用途在 Exactly Rounded Operations 中给出。

于 2015-04-06T22:40:44.837 回答