宽度不为1时梯形规则程序未完成(C)

时间:2016-04-06 04:36:55

标签: c for-loop increment

通过(上限 - 下限)/ 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;

2 个答案:

答案 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的相同值时,您已经意识到增量存在问题。