C语言中如何根据数组中f(x)值输出对应x(二次方程数值寻根)
问题说明
需要用数值搜索法求解二次方程 (ax^2+bx+c=0) 的根,禁止使用求根公式。当前代码已将不同x对应的f(x)值存入数组,能找到最接近0的f(x),但只能输出该f(x)值,无法输出对应的x(比如当a=1、b=-1、c=-6时,期望输出x=3而非f(x)=0)。
修改步骤
核心改法是找到最接近0的f(x)对应的数组索引,再根据索引反推x值(因为x的生成规则固定:(x = 0 + i \times 0.5))。具体修改如下:
1. 重写array_roots函数
原函数返回f(x)值,现在改成返回对应的x值:
- 新增变量记录最接近0的元素的索引和当前最小绝对值
- 遍历数组时,比较每个元素的绝对值,更新索引和最小绝对值
- 最后根据索引计算并返回对应的x值
修改后的函数代码:
float array_roots(const float table[], int length) { int i; int closest_index = 0; // 记录最接近0的元素的索引 float min_abs = fabs(table[0]); // 浮点数绝对值要用fabs() for(i=1; i<length; i++) { float current_abs = fabs(table[i]); // 找到绝对值更小的元素,更新索引和最小绝对值 if(current_abs < min_abs) { min_abs = current_abs; closest_index = i; } } // 和main里的x生成规则一致,计算对应的x return 0 + closest_index * 0.5; }
2. 修正细节问题
- 原代码用了
abs(),这是整数绝对值函数,浮点数应该用fabs()(已包含math.h,无需额外操作),避免精度丢失 - 去掉原代码里的
table[i] == 0判断,浮点数直接判等容易有精度误差,用绝对值比较更可靠
完整修改后的代码
/*================================================================== * Systems header files *==================================================================*/ #include <stdio.h> #include <math.h> #include <stdlib.h> /*================================================================== * Constant definitions *==================================================================*/ #define SIZE 50 /*================================================================== * Function definitions *==================================================================*/ float array_roots(const float [], int); int main(void) { float table[SIZE]; /* array to store the function values f(x) */ float a, b, c, x; int i; printf("*********************************************************\n"); printf("Welcome to the quadratic root estimator.\n"); printf("This estimates the value of one root of\n"); printf("f(x)=ax^2+bx+c.\n"); printf("*********************************************************\n"); printf("Enter the coefficients in the form \"a b c\"\n: "); scanf("%f %f %f",&a, &b, &c); /*populating array and calling function */ for(i=0; i<SIZE; i++) { x = 0 + i*(0.5); /* x范围:0到24.5(i从0到49)*/ table[i] = a*x*x + b*x + c; } printf("There is a root at: x = %.3f\n", array_roots(table, SIZE)); return(0); } /*//////////////////////////////////////////////*/ /*function outside of main to find x corresponding to f(x) closest to zero */ /*//////////////////////////////////////////////*/ float array_roots(const float table[], int length) { int i; int closest_index = 0; float min_abs = fabs(table[0]); for(i=1; i<length; i++) { float current_abs = fabs(table[i]); if(current_abs < min_abs) { min_abs = current_abs; closest_index = i; } } return 0 + closest_index * 0.5; }
补充说明
- 如果要调整x的搜索范围或步长,只要同步修改
main里的x生成公式和array_roots里的返回计算式,保持两者一致即可 - 该方法只能找到当前搜索范围内的一个根,如果二次方程的另一个根不在0到24.5之间,需要调整x的起始值、步长或者数组大小
内容的提问来源于stack exchange,提问作者Bon
相关产品推荐
相关产品推荐

