double z[110][110]; int n; doublegauss(){ double x = 1.0; for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) if(fabs(z[j][i]) > fabs(z[i][i])) { x = -x; for(int l = 1; l <= n; l++) swap(z[j][l], z[i][l]); } if(fabs(z[i][i] <= 1e-8)) return0.0; for(int j = i + 1; j <= n; j++) { double k = z[j][i] / z[i][i]; for(int l = 1; l <= n; l++) { z[j][l] = z[j][l] - z[i][l] * k; } } } for(int i = 1; i <= n; i++) x *= z[i][i]; return x; }
辗转相消法
对于所有数都为整数的行列式,虽然主元高斯消元法降低了误差, 但是并没有消除精度误差,计算过程中仍然在使用实数,所以可以使用类似辗转相除法的方法解决问题:用第 i+1 行减去第 i 行,然后交换两行位置,直到第 i 行等于0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int n, z[110][110]; intgauss(){ int ans = 1; for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) { while(z[j][i]) { int k = z[i][i] / z[j][i]; for(int l = 1; l <= n; l++) { z[i][l] = z[i][l] - z[j][l] * k; //比取模快 } for(int l = 1; l <= n; l++) swap(z[i][l], z[j][l]); ans = -ans; } } } for(int i = 1; i <= n; i++) ans *= z[i][i]; return ans; }