对于计算所有值的总和超过双精度值限制的平均值,什么是一个好的解决方案?
我需要计算一组非常大的双精度值(10^9 个值)的平均值。值的总和超过了双精度值的上限,那么有没有人知道计算平均值的巧妙的小技巧,而不需要计算总和?
我使用的是 Java 1.5。
我需要计算一组非常大的双精度值(10^9 个值)的平均值。值的总和超过了双精度值的上限,那么有没有人知道计算平均值的巧妙的小技巧,而不需要计算总和?
我使用的是 Java 1.5。
您可以迭代计算平均值。这个算法简单,快速,你必须只处理一次每个值,变量永远不会大于集合中的最大值,所以你不会得到溢出。
double mean(double[] ary) {
double avg = 0;
int t = 1;
for (double x : ary) {
avg += (x - avg) / t;
++t;
}
return avg;
}
循环内部始终是到目前为止处理的所有值的平均值。换句话说,如果所有值都是有限的,则不应溢出。avg
我想问你的第一个问题是:
如果没有,那么你别无选择,只能求和,计数,除以做平均值。如果精度不够高来处理这个问题,那么运气不好,你不能用,你需要找到一个可以处理它的数据类型。Double
Double
另一方面,如果您事先知道值的数量,则可以查看您真正在做什么并更改其操作方式,但保留整体结果。
存储在某个集合 A 中的 N 个值的平均值是:
A[0] A[1] A[2] A[3] A[N-1] A[N]
---- + ---- + ---- + ---- + .... + ------ + ----
N N N N N N
要计算此结果的子集,您可以将计算拆分为大小相等的集合,因此对于 3 值集可以执行此操作(假设值的数量可被 3 整除,否则需要不同的除数)
/ A[0] A[1] A[2] \ / A[3] A[4] A[5] \ // A[N-1] A[N] \
| ---- + ---- + ---- | | ---- + ---- + ---- | \\ + ------ + ---- |
\ 3 3 3 / \ 3 3 3 / // 3 3 /
--------------------- + -------------------- + \\ --------------
N N N
--- --- ---
3 3 3
请注意,您需要大小相等的集合,否则最后一个集合中的数字(与之前的所有集合相比没有足够的值)将对最终结果产生更大的影响。
按顺序考虑数字 1-7,如果选择 3 的集合大小,则得到以下结果:
/ 1 2 3 \ / 4 5 6 \ / 7 \
| - + - + - | + | - + - + - | + | - |
\ 3 3 3 / \ 3 3 3 / \ 3 /
----------- ----------- ---
y y y
它给出:
2 5 7/3
- + - + ---
y y y
如果 y 对于所有集合都是 3,则得到:
2 5 7/3
- + - + ---
3 3 3
它给出:
2*3 5*3 7
--- + --- + ---
9 9 9
即:
6 15 7
- + -- + -
9 9 9
总计:
28
-- ~ 3,1111111111111111111111.........1111111.........
9
1-7的平均值为4。显然,这行不通。请注意,如果您使用数字1,2,3,4,5,6,7,0,0(请注意最后两个零)进行上述练习,那么您将获得上述结果。
换句话说,如果无法将值的数量拆分为大小相等的集合,则最后一个集合将被计数,就好像它具有与它之前的所有集合相同的值数一样,但对于所有缺失值,它将用零填充。
因此,您需要同等大小的套装。如果您的原始输入集由素数值组成,则运气不好。
不过,我在这里担心的是精度的损失。我不完全确定在这种情况下会给你足够的精度,如果它最初不能容纳整个值的总和。Double