Как мне обработать возвращаемое значение inf - PullRequest
0 голосов
/ 20 февраля 2019

Я сам работаю над книгой на Си.Это не домашнее задание, которое нужно сдавать. Я пишу программу на 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

Есть ли способнам, если заявление типа:

Ответы [ 4 ]

0 голосов
/ 22 февраля 2019

Я хочу прерваться, когда вывод выдаст мне первый экземпляр: inf

Просто протестируйте INFINITY из <math.h>.Вывод не будет точным числом Фибоначчи .

#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 long и uintmax_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 type, это создать простую строку добавить функцию 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.
0 голосов
/ 20 февраля 2019

наибольшее число Фибоначчи, которое моя машина может произвестиОсновное правило Фибоначчи таково:

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

Вы можете взять переменную unsigned long long большого размера, и вы можете продолжать добавлять.Но что, если этот тип данных переполнен?Вы не связаны с типом данных.Ваша машина может выдавать число, даже большее, чем long long.Каким будет это число?Целые биты в оперативной памяти?Жесткий диск?

Поскольку от вас требуется использование итеративного, а не рекурсивного метода, ваш учитель / книга / инструктор может проверять вас на циклах (а не на любом стандартном 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

0 голосов
/ 20 февраля 2019

Только что провел небольшой поиск и нашел этот приятный трюк:

...
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; для выхода из процесса.

0 голосов
/ 20 февраля 2019

Самое простое - использовать INFINITY или isinf () .

...