C语言实现高斯消元时数组乘矩阵行仅首元素计算正确
C语言高斯消元行运算结果异常问题
问题现象
实现高斯消元法做矩阵行消元时,除首元素外,其余临时数组元素的计算结果均为-0,不符合预期。
异常相关代码如下:
float M[4][5] = { {99.69, 7.07, 53, -4, 155.76}, {-138.41, 14.11, -6.31, 5.6, -124.74}, {55, 35.174, 685, 1.4, 776.574}, {33, 21, -3.28, -0.28, 50.44} }; float t_arr[5] = {0,0,0,0,0}; for(int j = 0; j < 5; j++) { t_arr[j] = M[2][j]; t_arr[j] *= (-(M[3][0]/M[2][0])); printf("t_arr[%d] = %f\n",j, t_arr[j]); M[3][j] += t_arr[j]; }
异常触发代码行:
t_arr[j] *= (-(M[3][0]/M[2][0]));
预期逻辑:将矩阵M索引为2的行元素复制到t_arr后,所有元素统一乘以消元系数-(M[3][0]/M[2][0]),例如下标0的元素计算逻辑为55 * (-33/55) = -33。
实际运行输出:
t_arr[0] = -33.000000 t_arr[1] = -0.000000 t_arr[2] = -0.000000 t_arr[3] = -0.000000 t_arr[4] = -0.000000
仅首元素计算结果符合预期,其余元素结果异常。
问题根因
消元系数的计算逻辑放在了循环内部,被循环内的矩阵修改操作污染:
- 消元系数
-(M[3][0]/M[2][0])是固定值,本应在修改矩阵元素前提前计算。但现有代码在每轮循环中都会重新计算该系数,且系数依赖的M[3][0]会在第一轮循环(j=0)中被修改:j=0时执行M[3][j] += t_arr[j]后,原值为33的M[3][0]加上计算得到的t_arr[0]=-33,值变为0。 - j=1、2、3、4进入后续循环时,重新计算的系数分子为0,无论t_arr中存储的M[2][j]原值是多少,乘以0后结果都是0,最终输出全为-0(浮点数负零,本质为0)。
修复方案
在进入循环前提前计算固定的消元系数并存为变量,不要在循环内重复计算系数,避免依赖的矩阵元素被修改后系数失真。
修复后代码示例:
float M[4][5] = { {99.69, 7.07, 53, -4, 155.76}, {-138.41, 14.11, -6.31, 5.6, -124.74}, {55, 35.174, 685, 1.4, 776.574}, {33, 21, -3.28, -0.28, 50.44} }; float t_arr[5] = {0,0,0,0,0}; // 矩阵元素修改前提前算好固定消元系数 float eliminate_factor = -(M[3][0] / M[2][0]); for(int j = 0; j < 5; j++) { t_arr[j] = M[2][j]; t_arr[j] *= eliminate_factor; printf("t_arr[%d] = %f\n",j, t_arr[j]); M[3][j] += t_arr[j]; }
修复后运行可得到正确计算结果:首元素为-33,其余元素为M[2]对应行元素乘以系数-0.6的正确值,不会再出现全0异常。
内容的提问来源于stack exchange,提问作者fonabyatzz
相关产品推荐
相关产品推荐

