如何处理 return 值信息

How do I process the return value inf

我正在独自阅读一本关于 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;

最简单的就是使用INFINITY or isinf().

largest Fibonacci number my machine can produce

这个问题与任何数据类型无关,但与机器有关。

斐波那契的基本规则是这样的:

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

你可以取一个大的 unsigned long long 变量,你可以继续添加。但是,如果该数据类型溢出了怎么办?您不关心数据类型。您的机器可能会产生比 long long 更大的数字。那个数字是多少? RAM 上的全部位?硬盘 ?

由于您需要使用迭代方法而不是递归方法,因此您的 teacher/book/instructor 可能会在循环中测试您(而不是任何标准 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

刚刚做了一点搜索,发现了这个好技巧:

...
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;
...

事实证明,当 temp 达到 Inf 时,if 条件 temp - temp 产生 Nan,它什么都不等于,其余的只是执行 break; 到退出进程。

I want to to break when the output gives me the first instance of : inf

简单地针对 <math.h> 中的 INFINITY 进行测试。输出将不是 exact 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

整数

使用可用的最广泛的类型。这类似于 unsigned long long 方法。尽管 unsigned long longuintmax_t 具有相同的范围很常见,但使用 uintmax_t 可确保最宽。

uintmax_t: The following type designates an unsigned integer type capable of representing any value of any unsigned integer type:

  #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(),然后很容易形成 斐波那契数列。

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.