【问题标题】:Is it possible to predict when Perl's decimal/float math will be wrong? [duplicate]是否可以预测 Perl 的十进制/浮点数学何时会出错? [复制]
【发布时间】:2015-06-11 09:56:35
【问题描述】:

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

例如,在下面的代码中,当减法为“16.12 - 15.13”时,Perl 的数学错误 1 ​​次,当问题为“26.12 - 25.13”时错误 2 次,当问题为“36.12”时错误 20 次- 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";

【问题讨论】:

  • 在我的脚本顶部尝试“使用 bignum”,这使得 Math::BigFloat 对象的数字为我解决了这个问题。
  • (在评论中回答,因为问题已作为重复关闭。)是的,可以预测何时会发生浮点异常,因为 IEEE 浮点表示是确定性的。
  • 而且,Goldberg 经历了找出错误的细节。

标签: perl math binary decimal inexact-arithmetic


【解决方案1】:

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

舍入误差

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

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

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

【讨论】:

  • 这里的观点是正确的,即使我们正在处理,例如,使用十进制数字格式来表示超过该格式精度的十进制数字。在这种情况下,假设十进制数是有限精度的,所需要的只是提高十进制数格式的精度。相比之下,问题是说某些具有有限精度的 x 进制数不能使用任何有限精度的 y 进制格式来表示(如果 x 是 10 并且 y 是 2,情况就是这种情况)。
  • 其实这个问题很有趣,因为这个问题只有一个特定的值可见,如果使用 C 或 Perl 的printf 则无法观察到...只有当您打印特定操作的结果时使用 Perl 的 print 可能会导致 0.1 的后果无法精确表示,并且操作数的相对大小成为一个明显的问题。我的回答中的引用旨在引导读者详细讨论浮点,而不是在这里重新散列所有内容。
猜你喜欢
  • 1970-01-01
  • 2018-03-26
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多