逗号初始化和构造函数C ++和Eigen

时间:2017-07-07 23:38:52

标签: c++ matrix eigen

我在C ++中使用Eigen库,我试图找到矩阵的行列式。根据我如何初始化矩阵,我会得到不同的结果。

方法I:

MatrixXd a(3, 3);
for (int n = 0; n < 3; n++)
    for (int m = 0; m < 3; m++)
        a(n,m) = (double) (n + m*m + 2.5)/3;

cout << "Matrix a: " << endl;
cout << a << endl;
cout << "Determinat of matrix a is: " << a.determinant() << endl;

这部分代码打印

Matrix a:
0.8333333  1.166667  2.166667
1.166667       1.5       2.5
1.5  1.833333  2.833333
Determinat of matrix a is: -7.401487e-17

方法II:

MatrixXd b(3, 3);
b << 0.8333333, 1.166667, 2.166667,
    1.166667, 1.5, 2.5,
    1.5, 1.833333, 2.833333;

cout << b;
cout << endl << "Determinant of matrix b is: " << b.determinant();

打印

0.8333333  1.166667  2.166667
1.166667       1.5       2.5
1.5  1.833333  2.833333
Determinant of matrix b is: 2.333331e-07

方法I产生错误的结果,而方法II给出了正确的答案。第一种情况出了什么问题? (我使用的是Visual Studio。)提前致谢!

1 个答案:

答案 0 :(得分:5)

您在此处观察到的是计算中的舍入错误。让我解释一下:

对于计算机而言,一切都基于二进制数系统,即我们在日常生活中使用的基数10,而不是基数10,计算机用基数2计算,即只有数字0和1。

这不仅适用于整数,也适用于像0.83333这样的实数... 但就像无法写入0.83333的所有数字...,您的计算机无法存储此数字的二进制表示的每个最后一位数 - 因此它必须以某种方式舍入结果。

根据您初始化的方式(通过计算(n + m*m + 2.5)/3或通过读取逗号初始化中的值),结果可能会在最后一位数字中略有不同,从而导致不同的结果。< / p>

您可以通过将0.8333333与2.5 / 3进行比较来尝试这一点,这可能会返回false。如果您打印数字,则会得到相同的结果,但内部表示略有不同。

但是你应该注意到绝对误差本身很小(小于0.000001),所以你现在不必担心它。 如果您想要精确的结果,切换到可以准确表示这些值的有理数字类型可能会有所帮助。