Issue #10298 has been updated by Takeshi Nishimatsu.
Timing.
Of course it is fast.
$ uname -sprsv
Darwin 13.3.0 Darwin Kernel Version 13.3.0: Tue Jun 3 21:27:35 PDT
2014; root:xnu-2422.110.17~1/RELEASE_X86_64 i386
$ sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
$ ./miniruby --version
ruby 2.2.0dev (2014-09-29 trunk 47735) [x86_64-darwin13]
$ /usr/bin/time ./miniruby -e 'p Array.new(10000000,0.1).reduce(:+)'
999999.9998389754
0.66 real 0.62 user 0.03 sys
$ /usr/bin/time ./miniruby -e 'sum=0.0; c=0.0;
Array.new(10000000,0.1).each{|x|y=x-c; t=sum+y; c=(t-sum)-y; sum=t}; p
sum'
1000000.0
1.47 real 1.44 user 0.02 sys
$ /usr/bin/time ./miniruby -e 'p Array.new(10000000, 0.1).float_sum'
1000000.0
0.10 real 0.06 user 0.03 sys
Feature #10298: Array#float_sum (like math.fsum of Python)
- Author: Takeshi Nishimatsu
- Status: Open
- Priority: Low
- Assignee:
- Category: math
- Target version:
Here, I propose Array#float_sum in array.c (or math.c).
Array#float_sum returns an accurate total summation of Float
elements in an array using the Kahan summation algorithm
Kahan summation algorithm - Wikipedia .
This algorithm can significantly reduce the numerical
error in the total obtained by adding a sequence of
finite precision floating point numbers, compared to the
obvious approach. Python already have math.fsum
9.2. math — Mathematical functions — Python 2.7.18 documentation .
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1].float_sum #=> 1.0
[].float_sum #=> 0.0
Array.new( 10, 0.1).float_sum #=> 1.0
Array.new(100, 0.1).float_sum #=> 10.0
# cf.
Array.new( 10, 0.1).reduce(:+) #=> 0.9999999999999999
Array.new(100, 0.1).reduce(:+) #=> 9.99999999999998
The name of method can be fsum, sum_float, etc., though
I propose float_sum.
This Array#float_sum is inspired by Feature #9834
Float#{next_float,prev_float}.
—Files--------------------------------
array.float_sum.patch (1.32 KB)