【问题标题】:Got two methods, with same array, sane formula for conversion array elements. Methods returns different values有两种方法,具有相同的数组,转换数组元素的合理公式。方法返回不同的值
【发布时间】:2018-09-28 13:31:50
【问题描述】:

有两种方法,相同的数组,相同的转换数组元素的公式。方法返回不同的值。

数组大小:

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;
}

第二种方法: 将具有相同长度 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;

}

计算数量数组元素

    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 的结果应该相同。 我在哪里犯了错误?为什么返回值不同?

【问题讨论】:

  • 需要深度调试:)
  • 也许你的错误在这里 System.arraycopy(firstarr, 0, result, 0, h); System.arraycopy(secondarr, 0, result, h, h); 你有 h,h,我注意到你在其他地方没有相同的模式
  • h - size array/2 private static final int h = SIZE/2;
  • @ProgrammingNewb 那部分似乎是正确的。 System.arraycopy(src, srcPos, dest, destPos, length) 是该方法的签名

标签: java arrays


【解决方案1】:

您的问题在循环中。 第一种方法循环 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));
}

【讨论】:

    【解决方案2】:

    您在第二种方法中的问题是,您有 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]
    

    方法二: 两个数组:

    [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;
    } 
    

    【讨论】:

      猜你喜欢
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多