我知道类似的问题,但是我想征询人们对我的算法的意见,以求在实际成本上尽可能准确地求和浮点数。
这是我的第一个解决方案:
put all numbers into a min-absolute-heap. // EDIT as told by comments below pop the 2 smallest ones. add them. put the result back into the heap. continue until there is only 1 number in the heap.
这将需要O(n * logn)而不是普通的O(n)。真的值得吗?
第二种解决方案来自我正在处理的数据的特征。这是一个数量庞大的 正 数列表,具有 相似的数量级 。
a[size]; // contains numbers, start at index 0 for(step = 1; step < size; step<<=1) for(i = step-1; i+step<size; i+=2*step) a[i+step] += a[i]; if(i < size-1) a[size-1] += a[i];
基本思想是以“二叉树”方式进行求和。
注意:这是伪C代码。step<<=1表示乘以2。这将取O(n)。我觉得可能会有更好的方法。您可以推荐/批评吗?
step<<=1
Kahan的求和算法比直接求和算法精确得多,并且以O(n)运行(这取决于直接浮点与数据访问的速度,比直接求和慢1-4倍,在台式机上绝对慢4倍之多)。硬件,并且没有任何改组数据)。
或者,如果您使用的是普通的x86硬件,并且如果编译器允许访问80位long double类型,则只需将简单的求和算法与type的累加器一起使用long double。仅将结果转换为double最后。
long double
double
如果你真的需要大量的精密,您可以通过使用结合上述两种解决方案long double变量c,y,t,sum在Kahan的的总和算法。
c
y
t
sum