作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
到目前为止,我的直觉是一组数字的总和与它们相加的顺序无关。下面,随机数的集合由seed=0决定,但顺序由线程中的执行顺序决定。
我想使用多线程计算中的大量 double 之和作为校验和。有没有办法找到对总和中的组成数字最大敏感但对特定的随机加法序列不敏感的总和舍入方案?
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Test implements Callable<Double> {
public static class Sum {
double sum = 0;
public synchronized void add(double val) {
sum += val;
}
public double getSum() {
return sum;
}
};
Sum sum;
public Test(Sum sum) {
this.sum = sum;
}
@Override
public Double call() {
Random rand = new Random(0);
for (long i = 0; i < 1000000L; i++) {
sum.add(rand.nextDouble());
}
return 0D;
}
static double mean() {
Sum sum = new Sum();
int cores = Runtime.getRuntime().availableProcessors();
ExecutorService pool = Executors.newFixedThreadPool(cores);
ArrayList<Future<Double>> results = new ArrayList<>();
double x = 0;
for (int i = 0; i < cores; i++) {
Test test = new Test(sum);
results.add(pool.submit(test));
}
for (Future<Double> entry : results) {
try {
x += entry.get();
} catch (InterruptedException ex) {
throw new RuntimeException("Thread interrupted.", ex);
} catch (ExecutionException ex) {
throw new RuntimeException("Excecution exception:");
}
}
pool.shutdown();
return sum.getSum();
}
public static void main(String[] args) throws IOException {
for (int i = 0; i < 10; i++) {
System.out.format("Avg:%22.20f\n", mean());
}
}
}
最佳答案
假设您的数据结构已正确同步,则顺序不应影响最终总和,假设操作是可交换的。
换句话说,前提是 a + b
与 b + a
相同.
float 并非总是如此,因为它们毕竟是您想要的数字的近似值。
两个数字相加(上面的 a
和 b
)可能是可交换的,但当数字数量变大时,它会变得更加复杂。
例如,如果将尽可能小的数字与(相对)较大的数字相加,则只有一定精度的事实意味着您最终会得到较大的数字,例如:
-20
1 + 10 => 1
所以,如果你添加 10<sup>-20</sup>
至1
很多时候(准确地说是 1020),您仍然会得到 1
:
-20 -20 -20 -20 -20 -20
1 + 10 + 10 + 10 ... + 10 + 10 + 10 => 1
\__________________________________________/
20
10 of these
但是,如果您首先将所有这些 10<sup>-20</sup>
加在一起值,你最终会得到 1
(a),然后添加 1
会给你 2
:
-20 -20 -20 -20 -20 -20
10 + 10 + 10 ... + 10 + 10 + 10 + 1 => 2
\__________________________________________/
20
10 of these
<小时/>
(a) 这不一定完全正确,因为一旦累积量相对于 10<sup>-20</sup>
变得足够大,它就会停止增加。使该值对其影响为零。
但是,它不会处于累计金额为零的位置,因此您应该会看到最终金额的差异。
关于java - 数字之和是否取决于它们相加的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16660768/
我是一名优秀的程序员,十分优秀!