通过(上限 - 下限)/ n(期望的梯形数)找到宽度的方式,并且在我的代码中,当宽度为1时它可以工作但是如果它不是一个程序的东西将无法完成,我怀疑问题是我如何在“func”的for循环中递增它
代码:
#include <stdio.h>
#include <stdlib.h>
double func(double x) {
return x * x;
}
double trap(double lower, double upper, int n) {
double width,area = 0;
width = (upper - lower) / n;
//printf("%lf\n",width);
int i;
for (i = lower; i < upper; i += width) {
area += (func(i) + ((func(i + width)))) / 2 * width;
//printf("%lf\n",area);
}
return area;
}
int main(void) {
double lower,upper,x;
int n;
while (1) {
printf("lower limit: ");
scanf("%lf",&lower);
printf("upper limit (should be greater than %.2lf): ",lower);
scanf("%lf",&upper);
if (upper <= lower) {
printf("[ERROR] the lower limit must be less");
printf("than the upper limit: please try again\n");
continue;
}
printf("number of trapezoids: ");
scanf("%d",&n);
if (n <= 0) {
printf("[ERROR] the number of trapezoids must be");
printf("greater than 0; please try again\n");
continue;
}
break;
}
printf("%lf\n", trap(lower,upper,n));
return 0;
答案 0 :(得分:2)
问题在于循环增量。将width从double转换为int时,double的小数部分将被丢弃。这会导致(不包括)-1.0和1.0之间的任何宽度值转换为0.
答案 1 :(得分:0)
我同意analysis Tibrogargan,但不同意建议的补救措施。重复添加浮点值可能导致循环控制中累积错误的问题。循环控件应该用整数计数,并使用计数器计算每次迭代时x坐标的值。
我认为你应该使用类似于的循环:
double old_v = func(lower);
for (int i = 1; i < n; i++)
{
double x = lower + ((upper - lower) * i) / n;
double v = func(x);
area += width * (old_v + v) / 2.0;
old_v = v;
}
这可以将函数调用大约一半,以获得良好的衡量标准。通过注意每个值使用一次和最后一个值,并且所有中间值都使用两次,并且在每次迭代中乘以width
并除以2.0
,您可以进一步改进。因此。你可以使用:
double x_sum = func(lower) + func(upper);
for (int i = 1; i < n; i++)
x_sum += 2.0 * func(lower + ((upper - lower) * i) / n);
double area = x_sum * width / 2.0;
并且可能有其他技术可能甚至应该用于提高总和的稳定性。您可以将(upper - lower)
计算移出循环,但编译器仍然可能会这样做。
警告:未经测试的代码!
请注意,您应该使用调试器或通过向标识正在使用的值的trap()
函数添加print语句来调试代码。当您一遍又一遍地看到i
的相同值时,您已经意识到增量存在问题。