C语言矩形法计算atan(x)积分出现异常值的问题求助
问题根源分析与解决方案
核心问题:未初始化的数组元素
你的代码中,conv_array是局部定义的double数组,未进行初始化。C语言里,栈上的局部变量(包括数组)默认不会被初始化为0,初始值是栈内存中的随机垃圾数据。
当执行conv_array[i] += atan(linspace[j])*dx;时,第一次使用conv_array[i]时它的值是随机的:
- 若垃圾值接近0,累加后结果正常;
- 若垃圾值是极大数(比如你遇到的
2.308177e+268),累加后就会出现异常的极大值。
为什么修改数组长度后问题“消失”?
这只是巧合:
- 数组长度改变时,
conv_array在栈内存中的存储位置会变化,对应的初始垃圾值也会不同。 - 当你把长度改成18或100时,刚好
i=7、8、15对应的数组位置初始垃圾值接近0,所以结果看起来正常。但这不是真正的解决方法,换环境或执行时机,问题可能还会重现。
正确解决方案
有两种可靠的修复方式:
方式1:循环内初始化当前元素
在计算每个分箱的积分前,将conv_array[i]重置为0:
for (i = 0; i < num_conv; i++) { array_len_new = array_len + 10*i; double dx = 1./array_len_new; conv_array[i] = 0.0; // 关键:初始化当前元素为0 for (j = 0; j < array_len_new; j++) { linspace[j] = j* 1.0/array_len_new; conv_array[i] += atan(linspace[j])*dx; } printf("Result for %d bins is: %e\n", array_len_new, conv_array[i]); }
方式2:定义数组时全局初始化所有元素
定义conv_array时直接将所有元素初始化为0:
double conv_array[200] = {0};
(C语言规定,数组初始化时写{0}会自动将所有元素设为0)
额外优化建议
- 提升PI精度:你定义的
PI = 3.142857精度不足,建议使用标准库的M_PI(需先定义_USE_MATH_DEFINES再包含math.h),或更精确的数值3.141592653589793。 - 移除冗余数组:
linspace数组没必要保留,直接计算j*dx即可节省内存:
for (j = 0; j < array_len_new; j++) { double x = j * dx; conv_array[i] += atan(x) * dx; }
内容的提问来源于stack exchange,提问作者user2188518
相关产品推荐
相关产品推荐

