有两个方法,具有相同的数组,相同的转换数组元素公式。方法返回不同的值。
数组大小:
private static final int SIZE = 10000000;
private static final int h = SIZE/2;
第一种方法: 数组填充1,用新公式计算新值
private static float[] method1() {
float arr[] = new float[SIZE];
//array fill with 1,
for (int i = 0; i < arr.length; i++) {
arr[i] = 1;
}
//calulate new values with new formula
for (int i = 0; i < arr.length; i++) {
arr[i] = (float) (i * Math.sin(0.2f + i / 5) *
Math.cos(0.2f + i / 5) *
Math.cos(0.4f + i / 2));
}
//return new value
return arr;
}
第二种方法: Devide数组为两个,长度相同,为arr / 2, 分别计算每个的结果 编译回来一个
private static float[] method2(){
float arr[] = new float[SIZE];
float firstarr[] = new float[h];
float secondarr[] = new float[h];
float result[] = new float[SIZE];
for (int i = 0; i <arr.length ; i++) {
arr[i] = 1;
}
//Devide array in two with same length arr/2,
System.arraycopy(arr, 0, firstarr, 0, h);
System.arraycopy(arr, h, secondarr, 0, h);
for (int i = 0; i < firstarr.length; i++) {
firstarr[i] = (float) (i * Math.sin(0.2f + i / 5) *
Math.cos(0.2f + i / 5) *
Math.cos(0.4f + i / 2));
}
for (int i = 0; i < secondarr.length; i++) {
secondarr[i] = (float) (i * Math.sin(0.2f + i / 5)
* Math.cos(0.2f + i / 5)
* Math.cos(0.4f + i / 2));
}
//compile back in one
System.arraycopy(firstarr, 0, result, 0, h);
System.arraycopy(secondarr, 0, result, h, h);
// return result
return result;
}
Caclulate ammount array ellements
private static long amount(float[] arr){
long result = 0;
for (int i = 0; i <arr.length ; i++) {
result += arr[i];
}
return result;
}
public static void main(String[] args) {
System.out.println(amount(method1()));// ammount for first method: 22527562
System.out.println(amount(method2())); // ammount for second method: -20047478
}}
Method1的结果,而Method2应该是相同的。 哪里弄错了?为什么返回值不同?
答案 0 :(得分:2)
你的问题是循环的。 第一个方法循环i从0到N.第二个方法循环从i到N / 2两次。
例如: 对于N = 4,第一种方法返回
i=0 0.0
i=1 0.17....
i=2 0.066....
i=3 0.099....
但第二个:
i=0 0.0
i=1 0.17....
i=0 0.0
i=1 0.17....
所以可能的解决方案就是像这样改变第二个循环
for (int i = h; i < SIZE; i++) {
secondarr[i-h] = (float) (i * Math.sin(0.2f + i / 5)
* Math.cos(0.2f + i / 5)
* Math.cos(0.4f + i / 2));
}
答案 1 :(得分:1)
你在第二种方法中的问题是,你有2个相同的循环,产生相同的数组2次。 firstarr equals secondarr
。打印最终数组时,这一点就变得清晰了:
方法一:
[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638, -3.0198758, -3.3218634, -5.670701, -6.1432595, -2.9212573, 0.3833428, -0.48418152, -0.51444286, -1.0486217, -1.1068785]
方法2: 两个阵列:
[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]
[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]
最终阵列:
[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638, 0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]
这表明您必须更改第二个for-loop
以使用从h
开始并继续前进的值。如果您将此for-loop
用于secondarr
,则会得到相同的结果:
int counter = h;
for (int i = 0; i < secondarr.length; i++) {
secondarr[i] = (float) (counter * Math.sin(0.2f + counter / 5) * Math.cos(0.2f + counter / 5) * Math.cos(0.4f + counter / 2));
counter++;
}
作为一点注意事项,您不需要这些for-loops
中的任何一个,因为它们对您的程序没有任何作用:
for (int i = 0; i <arr.length ; i++) {
arr[i] = 1;
}