I was playing around with some toy examples of floating point rounding errors in Ruby, and I noticed the following behaviour which surprised me.
First, an unsurprising example, where the rounding error occurs:
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
Now try the same with Enumerable#sum
:
numbers.sum
#=> 1.0
The only thing I could find in the documentation that would hint at an explanation is
sum method may not respect method redefinition of “+” methods such as Integer#+.
so I suppose there's some kind of native code implementation in place to speed up things, but I would assume C floating points are also subject to IEEE-754 related imprecise arithmetic.
What is the reason for the behaviour in the second example? How is the sum
method able to avoid the rounding error?