#include #include #include #include using namespace std ; // examples of problematic sum lists float list1[] = {1, 1e15, 1, -1e15, -1, 1e15, 1, 1e15, 1, -1e15,-1, -1e15 } ; float list2[] = {1, 1e15, 1, -1e30, 1, 1e15, 1, 1e30, 1, -1e15, 1, -1e15, 1e-15, -1e-15 } ; //--------------------------------------------------------------------------- // Typical naive summation routine using floating point data //--------------------------------------------------------------------------- float naive_sum(float l[], int n) { float s = l[0] ; for(int i=1;i fabs(l[i])) // Estimate roundoff error component c += (sum - t) + l[i] ; else c += (l[i] - t) + sum ; sum = t ; } return sum + c ; // Final sum is the combination of roundoff and total } //--------------------------------------------------------------------------- // Pairwise summation approach has lower error, break sum into a tree // this makes the roundoff error growth only log(n) //--------------------------------------------------------------------------- float pair_sum(float l[], int n) { vector scratch(n) ; for(int i=0;i 1) { // Repeat adding consecutive pairs until only 1 number remains //#define SHOW #ifdef SHOW for(int i=0;i scratch(n) ; for(int i=0;i