On Saturday, 18 October 2014 at 10:44:59 UTC, Ola Fosheim Grøstad wrote:
On Saturday, 18 October 2014 at 08:21:47 UTC, eles wrote:
On Saturday, 18 October 2014 at 05:54:01 UTC, Ola Fosheim Grøstad wrote:
On Saturday, 18 October 2014 at 04:35:07 UTC, Walter Bright wrote:

Larger mantissa can help a little bit, but only a little bit.

https://en.wikipedia.org/wiki/Kahan_summation_algorithm

Kahan helps a little bit:


a = [math.pi*(n**9) for n in range(0,101)]
      +[-math.pi*(n**9) for n in range(100,0,-1)]

print sum(a), kahan(a), fsum(a)

-1389.4713685 239.156561184 0.0


but not a lot:


a = [1e16,math.pi,-1e16]

print sum(a), kahan(a), fsum(a)

4.0 4.0 3.14159265359


a = [1e17,math.pi,-1e17]

print sum(a), kahan(a), fsum(a)

0.0 0.0 3.14159265359

auto kahanSum(R)(R input)
{
    double sum = 0.0;
    double c = 0.0;
    foreach(double el; input)
    {
        double y = el - c;
        double t = sum + y;
        c = (t - sum) - y;
        sum = t;
    }
    return sum;
}               

import std.math;
import std.range;
import std.algorithm;
import std.stdio;

double pi = PI;

void main()
{
    auto a = chain(
            iota(101L).map!((x) => pi * x^^9),
            iota(101L).map!((x) => -pi * x^^9)
        );
    writeln(kahanSum(a));
    writeln(a.sum);
}

$ rdmd kahantest.d
0
-980

Reply via email to