【问题标题】:why the double matrix results is different from the integer matrix results in java为什么双矩阵结果与java中的整数矩阵结果不同
【发布时间】:2016-11-29 18:07:27
【问题描述】:

我有两个代码来做完全相同的事情,唯一的区别是在第一个代码中我使用的是整数数组,而在第二个代码中我使用的是双精度数组。第一个代码运行良好,但第二个代码有很多错误。 两个代码,假设循环通过第一个矩阵“pathPoints”,从内部的小数组中获取所有路径并从“F”矩阵中获取它们的权重,然后将所有这些权重加在一起并输出,我附上了两个代码:

public class PathFlowCalculator {

    static final int N = 6;

    private final int[][][] pathPoints = {
            { { 0 }, { 0, 1 }, { 0, 3, 2 }, { 0, 3 }, { 0, 3, 2, 4 }, {0, 5 } },
            { { 1, 2, 4, 0 }, { 1 }, { 1, 2 }, { 1, 2, 3 }, { 1, 2, 4 }, { 1, 5  } },
            { { 2, 4, 0 }, { 2, 4, 1 }, { 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 } },
            { { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3 }, { 3, 2, 4}, { 3, 1, 5 } },
            { { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4 }, { 4, 1, 5 } },
            { {  5, 2, 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 2, 4 }, { 5 } }
    };
    private final int[][] F = {
            {0, 9, 11, 12, 8, 12},
            {18, 0, 15, 10, 17, 18},
            {17, 18, 0, 14, 10, 10},
            {17, 8, 10, 0, 17, 18},
            {15, 9, 12, 14, 0, 16},
            {18, 16, 15, 8, 9, 0}
    };

    // this is where we store results
    private final int[][] flowPerStep = new int[N][N];

    public PathFlowCalculator() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                int[] currentPath = pathPoints[i][j];
                int currentFlow = F[i][j];
                for (int k = 0; k < currentPath.length - 1; k++) {
                    int fromNode = currentPath[k];
                    int toNode = currentPath[k + 1];
                    flowPerStep[fromNode][toNode] += currentFlow;
                }
            }
        }
    }

    //This is the main method

    public static void main(String... argv) {

        //Declaring couple of arrays to be used inside this function to store the results in
        //So that I can pass the results later
        long startTime  = System.currentTimeMillis();

        PathFlowCalculator calc = new PathFlowCalculator();
        for (int o=0; o<N; o++){
            for(int p=0;p<N;p++){
                System.out.print(calc.flowPerStep[o][p]+ "     ");
            }
            System.out.println();

            //The same function I used in FloydWarshall.java to compute the CPU usage and load

        }

    }

}

这个输出是完美的:

0     9     0     31     0     12     
0     0     60     0     0     52     
0     0     0     24     132     10     
17     26     46     0     0     0     
68     43     12     14     0     0     
0     16     42     8     0     0  

这是第二个代码,除了 F 矩阵现在是双精度的,我希望输出也是双精度的,我只是更改了字段的名称

public class Actual {

    static final int N = 6;
    final static int INF = 999999999;


    private final int[][][] path = {
            { { 0 }, { 0, 1 }, { 0, 3, 2 }, { 0, 3 }, { 0, 3, 2, 4 }, {0, 5 } },
            { { 1, 2, 4, 0 }, { 1 }, { 1, 2 }, { 1, 2, 3 }, { 1, 2, 4 }, { 1, 5  } },
            { { 2, 4, 0 }, { 2, 4, 1 }, { 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 } },
            { { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3 }, { 3, 2, 4}, { 3, 1, 5 } },
            { { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4 }, { 4, 1, 5 } },
            { {  5, 2, 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 2, 4 }, { 5 } }
    };
    private final double[][] FF = {
            {0.0, 19.6, INF, 79.33, INF, 21.0},
            {INF, 0.0, 42.5, INF, 10, 42},
            {9.0, 10.0, 0.0, 29.33, 180.0, 13.5},
            {30.86, 15.56, 11.2, 0.0, INF, INF},
            {207.0, 48.0, 23.33, 150.0, 0.0, INF},
            {INF, 85.0, 120.0, 18.89, INF, 0.0}
    };

    // this is where we store results
    private final double[][] result = new double[N][N];

    public Actual() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                int[] current = path[i][j];
                double currentFlow = FF[i][j];
                for (int r = 0; r < current.length - 1; r++) {
                    int from = current[r];
                    int to = current[r + 1];
                    result[from][to] += currentFlow;
                }
            }
        }
    }

    public static void main(String... args) {

        Actual calcc = new Actual();
        for (int w=0; w<N; w++){
            for(int e=0;e<N;e++){
                System.out.print(calcc.result[w][e]+ "     ");
            }
            System.out.println();

        }

    }

}

但我的输出错误如下:

0.0     19.6     0.0     2.00000007733E9     0.0     21.0     
0.0     0.0     2.0000000505E9     0.0     0.0     2.00000004E9     
0.0     0.0     0.0     1.00000002833E9     5.000000204E9     13.5     
30.86     1.00000001456E9     3.0000000082E9     0.0     0.0     0.0     
2.000000214E9     1.000000057E9     23.33     150.0     0.0     0.0     
0.0     85.0     2.000000118E9     18.89     0.0     0.0 

请有人解释一下为什么会这样,提前谢谢!

【问题讨论】:

    标签: java arrays loops matrix double


    【解决方案1】:

    这是溢出的情况。考虑以下两个示例:

        double x = 79.33+999999;
        System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(x)));
        System.out.println(x);
    
      Result:   
        100000100101110100001010001110010101000111101011100001010001111
        1000078.33
    

    上面的效果很好。

    现在,如果我添加 9999999

        double x = 79.33+9999999;
        System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(x)));
        System.out.println(x);
    
    Result:
        100000101100011000100101101100111001010100011110101110000101001
        1.000007833E7
    

    希望这会有所帮助!

    【讨论】:

    • 非常感谢@codepi,但即使我将 INF 更改为 0,我仍然会有一些错误的答案,在某些情况下答案应该只有 90,但我仍然会得到很长的数字
    猜你喜欢
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 2016-12-19
    • 2020-08-11
    相关资源
    最近更新 更多