I've noticed array.sum
and array.inject(:+)
produce different results. What's the reason for this?
a = [10, 1.1, 6.16]
a.inject(:+)
# => 17.259999999999998
a.sum
# => 17.26
I've noticed array.sum
and array.inject(:+)
produce different results. What's the reason for this?
a = [10, 1.1, 6.16]
a.inject(:+)
# => 17.259999999999998
a.sum
# => 17.26
The C implementation of Array#sum
delegates to the Kahan summation algorithm when some of its inputs are floating point numbers.
This algorithm ...
...significantly reduces the numerical error in the total obtained by adding a sequence of finite precision floating point numbers, compared to the obvious approach. This is done by keeping a separate running compensation (a variable to accumulate small errors).
-- Wikipedia
See Array#sum and the implementation on Github.
© 2022 - 2024 — McMap. All rights reserved.
sum
probably uses native code; if so, it can be optimized, but also means it doesn't have to do the exact same sequence of rounding to a double-64 each step. What is the result of[10, 15, 1.1, 2, 6.16, 1].sum
? What about10 + 15 + 1.1 + 2 + 6.16 + 1
? Those should show the same behavior "deviations" as the code in the question. – Partidasum
works in a different order. – Susurrationsum
not only for performance but for accuracy when adding floating point numbers, thanks for this. It's pretty informative to look at the amount of complexity that exists in the C implementation of something as (seemingly) trivial asArray#sum
. – Roentgenogram