【发布时间】:2019-12-15 02:18:42
【问题描述】:
我正在玩一些 Ruby 中浮点舍入错误的玩具示例,我注意到以下行为让我感到惊讶。
首先,一个不足为奇的例子,发生舍入误差:
numbers = Array.new(10, 0.1)
#=> [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
numbers.inject(0, :+)
#=> 0.9999999999999999
现在用Enumerable#sum试试同样的方法:
numbers.sum
#=> 1.0
我能在文档中找到的唯一提示解释是
sum 方法可能不尊重 Integer#+ 等“+”方法的方法重定义。
所以我认为有某种本机代码实现可以加快速度,但我认为 C 浮点数也受 IEEE-754 相关的不精确算术约束。
第二个示例中的行为的原因是什么? sum 方法如何避免舍入误差?
【问题讨论】:
-
sumsource 中的一条评论指向A Generalized Kahan-Babuška-Summation-Algorithm,这就解释了为什么sum更准确。 -
这一定是答案。谢谢!试图搜索这个词,我找到了en.wikipedia.org/wiki/Kahan_summation_algorithm,它很好地解释了一般原则。
标签: ruby algorithm floating-point ieee-754 enumerable