sch*_*itz -2 math binary perl decimal inexact-arithmetic
在一个方面,我理解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";
Run Code Online (Sandbox Code Playgroud)
这些都不是Perl特有的.见戈德堡:
舍入误差
将无限多个实数压缩成有限数量的比特需要近似表示.尽管存在无限多个整数,但在大多数程序中,整数计算的结果可以以32位存储.相反,给定任何固定数量的位,大多数具有实数的计算将产生无法使用那么多位精确表示的量.因此,浮点计算的结果通常必须舍入,以便适应其有限表示.该舍入误差是浮点计算的特征."相对错误"和"Ulps"部分描述了它的测量方式.
由于大多数浮点计算无论如何都有舍入误差,如果基本算术运算引入的舍入误差比必要的多一点,是否重要?这个问题是本节的主题.Guard Digits部分讨论了保护数字,这是减去附近两个数字时减少错误的一种方法.IBM认为保护数字非常重要,它在1968年为System/360体系结构中的双精度格式添加了一个保护数字(单精度已经有一个保护数字),并对现场的所有现有机器进行了改造.给出两个例子来说明保护数字的效用.
IEEE标准不仅仅要求使用保护数字.它给出了加法,减法,乘法,除法和平方根的算法,并要求实现产生与该算法相同的结果.因此,当程序从一台机器移动到另一台机器时,如果两台机器都支持IEEE标准,则基本操作的结果在每一位都是相同的.这极大地简化了程序的移植.精确规范的其他用途在Exactly Rounded Operations中给出.