2013-02-14 299 views
0

我正在写一个二分法算法来找到多项式的根。我的代码的第二部分说,如果FP等于零或绝对值b-a它只是打破了我猜的if语句。如何摆脱循环c

我希望程序完全停止for循环(迭代)并返回p。最后,我想打印获得解决方案所需的迭代次数,但显然使用我的printf语句,它显示程序仍然执行,即使认为获得了根(零)。

任何关于如何停止整个机制的想法,并返回p的值为零和确切的迭代次数?由于

double computeroots(double a, double b, double epsilon, int MaxIter) 
{ 
    double FA = pow(a,4) -4*a + 1; 
    double FB = pow(b,4) - 4*b + 1; 
    double FP; 
    double p; 
    int i; 

    for(i=0;i<MaxIter;i++) { 
     if(FA * FB < 0) { 
      p = a + (b-a)/2; 
      FP = pow(p,4) - 4*p +1; 
      if(FP == 0 || abs(b-a) < epsilon) { 
       return p; 
       break; 
      } else if (FA * FP >0) { 
       a =p; 
       FA = FP; 
      } else { 
       b = p; 
       FB = FP; 
      } 
      i++; 
     } 
    } 

    printf("the number of iterations is : %d\n", i); 
} 
+1

我没有改变你的标题第二递增,但它绝对是误导性的。你只有一个循环,而不是外部循环和嵌套循环。 – 2013-02-14 15:15:57

+0

你正在增加'i'两次,所以你只运行一半的迭代。 – 2013-02-14 15:16:36

回答

3

printf语句不打,因为你有break语句前return p;。 A return语句立即退出该功能。

您需要printf后到return声明移到或移动printfreturn

 if(FP == 0 || abs(b-a) < epsilon) 
     { 
      printf("the number of iterations is : %d\n", i); 
      return p; 
     } 
     ... 

    printf("failed to converge after %d iterations\n", i); 
    return p; 
} 
+2

或者离开休息时间并将'return'移动到函数的末尾(它属于!) – 2013-02-14 15:26:47

0

您可以返回双打,其中第一个元素是结果的数组,而第二一个是迭代次数。

或者,您通过引用变量的函数,并分配给它,就像这样:

double compute_something(int param1, int param2, int* iterations) { 
    // your code ... 
    // when you want to return, use this: 
    *iterations = 5; 
    return 1.23; 
    // your code ... 
} 

int iter; 
double result = compute_something(1,2, &iter); 

在此之后,结果中包含的结果,ITER你存储的迭代次数。 该解决方案可能会更好,因为您没有将迭代次数(显然是整数)返回为double。

1

如果您有return声明,那么您的break声明是无用的。返回值退出函数的范围并返回给调用者,以便以后不再执行任何指令。

所以这个:

return p; 
break; 

应该变成:

printf("the number of iterations is : %d\n", i); 
return p; 

如果你看到退出条件选择不正确我猜想它更是一个有限精度问题。您正在检查​​,但FPdouble,所以您必须在FP足够接近0时停止,而不是当它完全相等时停止。例如:abs(FP) < epsilon

0

当你需要返回多个值时,你可以用out-arguments来完成。你的函数改为

double computeroots(double a, double b, double epsilon, int MaxIter, int *numIterations) 

调用它像这样:

int numIter; 
soln = computeroots(a, b, epsilon, MaxIter, &numIter); 

,并在你的函数,只是返回之前,添加:

*numIterations = i; 
+0

谢谢阿德里安你保存了这一天..但是我不明白的是你说的是computeroots应该期望一个指向numIterations的整数的指针吧!到目前为止这么好,当你调用它时,你使用&符号,这也是好的,因为它是一个指针..但是令人困惑的是你声明numIterations是一个整数而不是指向整数的指针..哪些工作很好,但我仍然感到困惑,我们应该声明int * numIterations主要不只是int numIterations – user2059456 2013-02-16 17:35:29

+0

当我想在printf中显示numIterations的值时,它返回一个不兼容的警告。我说printf(“.....”,* numIterations);这是错误的我知道不应该有一个星号,但我不明白为什么。由于它是一个指针,它应该在它之前得到星号以便返回它指向的值。没有星号,它应该返回它指向的变量的地址而不是值...任何说明请 – user2059456 2013-02-16 17:39:20

+0

这不是一个指针。这是一个正常的整数购买,你通过引用该函数传递它:&可以被翻译为“内存方向...”。所以在你使用的函数*(这是间接运算符,你可能会觉得有用的翻译为“内存方向的内容...”)。 你可以使用正常变量的内存引用,它们不一定必须是指针。 – 2013-02-16 17:46:20

0

要合并所有必要的mods/S:

double computeroots(
    double a, 
    double b, 
    double epsilon, 
    size_t MaxIter, 
    size_t * pNumIter 
) 
{ 
    double FA = pow(a,4) -4*a + 1; 
    double FB = pow(b,4) - 4*b + 1; 
    double FP; 
    double p = NaN; 
    size_t i; 

    for(i=0; i<MaxIter; ++i) { 
     if(FA * FB < 0) { 
      p = a + (b-a)/2; 
      FP = pow(p,4) - 4*p +1; 
      if(FP == 0 || abs(b-a) < epsilon) { 
       break; 
      } else if (FA * FP >0) { 
       a =p; 
       FA = FP; 
      } else { 
       b = p; 
       FB = FP; 
      } 
     } 
    } 

    *pNumIter = i; 

    printf("the number of iterations is : %z\n", *pNumIter); 

    return p; 
} 

这样调用它:上模/ s的

double a, b, epsilon; 
size_t sizeMax, sizeIterations; 

... /* some initialisations here */ 

double d = computeroots(a, b, epsilon, sizeMax, &sizeIterations); 

注:

  • 除去错位的return
  • 加入缺少在端返回
  • 改变int s至是size_t,作为unsigned型西服计数器
  • 更好
  • 添加引用addtionaly size_t变量返回迭代次数
  • 删除的i