我如何处理inf的返回值

时间:2019-02-20 05:42:14

标签: c floating-point break

我自己研究有关C的书。这不是要交的作业。我正在编写一个C程序来确定我的机器可以产生的最大斐波那契数。并指示使用非递归方法。

我的代码:

#include<stdio.h>
double fibo(int n);
int main(void)
{
    int n = 0; // The number input by the user
    double value; // Value of the series for the number input

    while (n >= 0)
    {

       // Call fibo function

       value = fibo(n);

       // Output the value

       printf("For %d the value of the fibonacci series = %.0f\n", n, 
       value);


       n++;

    }

   return 0;
}

double fibo(int n)
{

  int i; // For loop control variable
  double one = 0; // First term
  double two = 1; // Second term
  double sum = 0; // placeholder

  if (n == 0)
      return 0;
  else if (n == 1)
      return 1;
  else
  {
     for (i = 2; i <= n; i++)
     {
        sum = one + two;
        one = two;
        two = sum;
     }
  }

return sum;

代码可以正常工作,但是当输出给我第一个实例时,我想中断代码:

For 17127 the value of the fibonacci series = inf

是否可以通过以下方式获得if语句:

if (value == inf)
  break;

4 个答案:

答案 0 :(得分:4)

最简单的方法是使用INFINITYisinf()

答案 1 :(得分:2)

只需稍作搜索,就会发现这个不错的窍门:

...
double value, temp; // Value of the series for the number input

while (n >= 0)
{

   // Call fibo function

   temp = fibo(n);
   if (temp - temp != 0)
        break;
   else
        value=temp;
...

好吧,事实是发生了什么事,当温度达到Inf时,if条件temp - temp产生了Nan,它等于空,其余的只是执行break;退出了过程。

答案 2 :(得分:1)

  

我的机器可以产生的最大斐波那契数

此问题与任何数据类型无关,但与计算机有关。

斐波那契的基本规则是:

n = (n-1) + (n-2)

您可以使用大型unsigned long long变量,并且可以继续添加。但是,如果该数据类型溢出怎么办?您不关心数据类型。您的机器产生的数字可能甚至大于long long。这个数字是多少? RAM上的整个位?硬盘?

由于您需要使用迭代方法而不是递归方法,因此您的老师/书本/讲师可能正在循环测试您(而不是任何标准API)。以下是使用unsigned long long的示例代码:

#include <stdio.h>

int main ()
{

  unsigned long long a = 0;
  unsigned long long b = 1;

  unsigned long long c = a + b;


  while(c >= b)
  {
     a = c;
     c = b + c;
     b = a;
  }

  printf("\n%llu\n", b);

  return 0;

}

输出:

12200160415121876738

答案 3 :(得分:1)

  

当输出为我提供inf

的第一个实例时,我想休息一下

只需针对INFINITY中的<math.h>进行测试。输出将不是完全 Fibonacci number

#include <math.h>
#include <stdio.h>

int main(void) {
  double a;
  double b = 0;
  double c = 1;
  do {
    a = b;
    b = c;
    c = a + b;
  } while (c < INFINITY);
  printf("%e\n", b);
  return 0;
}

输出

1.306989e+308

long double

使用最宽的浮点类型并查找不精确的加法。

#include <fenv.h>
#include <stdio.h>

int main(void) {
  long double a;
  long double b = 0;
  long double c = 1;
  do {
    a = b;
    b = c;
    c = a + b;
  } while (fetestexcept(FE_INEXACT) == 0);
  printf("%.0Lf\n", b);
  return 0;
}

输出

12200160415121876738

整数

使用最宽的类型。这类似于@Syed.Waris unsigned long long方法。尽管unsigned long longuintmax_t具有相同的范围是常见的,但使用uintmax_t可以确保最宽。

  

uintmax_t:以下类型指定了一种无符号整数类型,该类型能够表示任何无符号整数类型的任何值:

  #include <stdint.h>
  #include <stdio.h>

  uintmax_t a;
  uintmax_t b = 0;
  uintmax_t c = 1;

  do {
    a = b;
    b = c;
    c = a + b;
  } while(c >= b);
  printf("%ju\n", b);

输出

12200160415121876738

字符串

double或某些int类型的替代方法是创建一个简单的 string 添加函数str_add(),然后很容易形成 large 斐波那契数。

int main(void) {
  char fib[3][4000];
  strcpy(fib[0], "0");
  strcpy(fib[1], "1");
  int i;
  for (i = 2; i <= 17127 && strlen(fib[1])  < sizeof fib[1] - 1; i++) {
    printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
    strcpy(fib[0], fib[1]);
    strcpy(fib[1], fib[2]);
  }
  printf("%zu\n", strlen(fib[2]));
  return 0;
}

输出

Fib(1476) 13069...(299 digits)....71632.  // Exact max `double`
Fib(17127) 95902...(3569 digits)...90818.