是否可以预测Perl的十进制/浮点数何时会出错?

时间:2015-04-06 22:36:49

标签: perl math binary decimal inexact-arithmetic

从某个方面来说,我理解Perl的浮点数是不精确的二进制表示,这导致Perl的数学运算有时是错误的。我不明白的是,为什么有时候这些花车似乎给出了确切的答案,有时则不然。 是否有可能预测Perl的浮动数学何时会出错(即不准确的答案)?

例如,在下面的代码中,当减法为" 16.12 - 15.13"时,Perl的数学错误1次,当问题出现时错误2次" 26.12 - 25.13",当问题出现时错误20次" 36.12 - 35.13"。此外,由于某些原因,在所有上述测试用例中,我们的减法问题(即$ 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";

1 个答案:

答案 0 :(得分:5)

这些都不是Perl特有的。见Goldberg

  

舍入错误

     

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

     

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

     

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