C++计算雅可比方法向量无穷范数相对误差结果异常排查
问题分析与解决方案:雅可比方法相对误差计算异常
嘿,我帮你找出问题所在了!你的代码里有两个关键bug导致了这个不符合预期的结果,咱们一步步来看:
1. 数组作为函数参数时,sizeof无法正确获取数组长度
当你把数组传递给函数时,它会自动退化为指向第一个元素的指针——这意味着在infinite_norm和subtract_vectors函数里,sizeof(b)或者sizeof(x)得到的是指针的大小(比如64位系统下是8字节),而不是数组的实际元素个数。你的数组有4个double元素,每个占8字节,原数组总大小是32字节,但函数里的sizeof返回8,导致循环次数错误(甚至会访问越界内存,引发未定义行为)。
2. subtract_vectors函数修改了原数组,导致后续计算错误
你的subtract_vectors直接修改了传入的x数组,把它变成了x-y的结果。这就导致在relative_error函数里,先调用infinite_norm(subtract_vectors(x, y))修改了x,然后再调用infinite_norm(x)时,用的已经是修改后的数组了!比如你的原数组b是{6.,25.,-11.,15.},减去c后变成{5.,24.,-12.,14.},它的无穷范数是24,所以24/24=1,这就是你得到错误结果的直接原因。
修正后的代码
#include <iostream> #include <cmath> // 用C++标准头文件cmath替代C风格的math.h using namespace std; // 增加数组长度参数n,明确告诉函数要处理多少个元素 double infinite_norm(double b[], int n) { double maximum = fabs(b[0]); for(int i = 1; i < n; ++i) { double current_abs = fabs(b[i]); if(current_abs > maximum) { maximum = current_abs; } } return maximum; } // 创建新数组存储差值,不修改原数组x和y double* subtract_vectors(double x[], double y[], int n) { double* diff = new double[n]; for(int k = 0; k < n; ++k) { diff[k] = x[k] - y[k]; } return diff; } double relative_error(double x[], double y[], int n) { // 先计算原数组x的无穷范数,避免被后续操作修改 double original_x_norm = infinite_norm(x, n); double* diff = subtract_vectors(x, y, n); double diff_norm = infinite_norm(diff, n); delete[] diff; // 记得释放动态分配的内存,避免泄漏 return diff_norm / original_x_norm; } int main() { double b[] = {6., 25., -11., 15.}; double c[] = {1., 1., 1., 1.}; // 计算静态数组的元素个数:总大小除以单个元素大小 int array_size = sizeof(b) / sizeof(b[0]); cout << relative_error(b, c, array_size) << endl; cout << 24. / 25. << endl; return 0; }
关键修正点说明
- 给所有操作数组的函数增加了
n参数,用sizeof(b)/sizeof(b[0])在main中计算数组长度,这是C++中获取静态数组元素个数的标准方法。 subtract_vectors现在动态创建新数组存储差值,不会修改原数组,保证计算原数组无穷范数时用的是原始数据。- 替换
math.h为cmath,遵循C++标准头文件规范。 - 释放了动态分配的数组内存,避免内存泄漏问题。
运行修正后的代码,你就能得到预期的0.96(也就是24/25)啦!
内容的提问来源于stack exchange,提问作者Tobal
相关产品推荐
相关产品推荐

