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



我在C++中使用特征库,我试图找到矩阵的行列式。根据我初始化矩阵的方式,我得到了不同的结果。

方法一:

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

方法二:

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。提前感谢!

您在这里观察到的是计算中的舍入误差。让我这样解释:

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

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

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

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

但是,您应该注意,绝对误差本身非常小(小于0.000001(,因此您目前无需担心。 如果您想要确切的结果,切换到可以精确表示这些值的有理数类型可能会有所帮助。

最新更新