2

I working through a book on C on my own. This isn't homework to be turned in. I am writing a C program to determine the largest Fibonacci number my machine can produce. And instructed to use a nonrecursive method.

My Code:

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

Code works fine but I want to to break when the output gives me the fist instance of :

For 17127 the value of the fibonacci series = inf

Is there way to us an if statement like:

if (value == inf)
  break;
alinsoar
  • 15,386
  • 4
  • 57
  • 74
Jay
  • 75
  • 1
  • 9
  • That loop in the `main` function, when is it supposed to end? If you want to add a special condition that `break` the loop, why have a conditional loop anyway? Especially one that could lead to signed integer arithmetic overflow (which is *undefined behavior*). – Some programmer dude Feb 20 '19 at 05:44
  • It is not. It is left infinite on purpose to see how big the numbers get. I am hoping that i can make it stop when a particular value appears – Jay Feb 20 '19 at 05:46
  • It's only infinite in theory. In practice all integer values on a computer are limited. And as mentioned, arithmetic overflow of signed integers (which will happen with `n++` when you cross the limit of `int`) in C leads to undefined behavior. – Some programmer dude Feb 20 '19 at 05:50
  • 1
    you probably should at least check man(3) isinf() and fpclassify(), inf is not intend to be used as in your code. – KL-Yang Feb 20 '19 at 05:53
  • Easy enough to put numbers in and make it stop. Will do. Thanks – Jay Feb 20 '19 at 05:55

4 Answers4

4

The simplest is to use INFINITY or isinf().

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
2

Just did a little search and found this nice trick:

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

well it turns out that whats happening is when temp hits Inf the if condition temp - temp produces Nan which equals nothing and the rest is just executing break; to exit the process.

  • 1
    The explanation is wrong. This works because `Inf - Inf` produces `Nan`, which is unequal to everything, including itself. – Alexey Frunze Feb 20 '19 at 07:10
  • @AlexeyFrunze it turns out that you are correct, there is no need to typecast one of `temp`s. An if condition like `(temp - temp != 0)` or just `(temp - temp != any_number)` seems to do the job since all of them produce `Nan`. – Curious Student Feb 20 '19 at 07:21
1

largest Fibonacci number my machine can produce

This question is not concerned with any data type but it is concerned with machine.

The basic rule of fibonacci is this:

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

You can take a big sized unsigned long long variable and you can keep on adding. But what if that datatype is overflowed? You are not concerned with data type. Your machine may produce a number even bigger than the long long. What would that number be ? Entire bits on RAM? Hard Disk ?

Since you are required to use an iterative method and not recursive method, your teacher/book/instructor might be testing you on loops (and not any standard API). Below is sample code using 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;

}

Output:

12200160415121876738

Syed Waris
  • 1,056
  • 1
  • 11
  • 16
1

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

Simply test against INFINITY from <math.h>. The output will not be an 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;
}

Output

1.306989e+308

long double

Use the widest floating point type and look for an inexact addition.

#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;
}

Output

12200160415121876738

Integers

Use the widest type available. This is akin to @Syed.Waris unsigned long long approach. Although common that unsigned long long and uintmax_t have the same range, using uintmax_t insures the widest.

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

Output

12200160415121876738

String

An alternative to double or some int type, is to create a simple string add function str_add(), then quite easy to form large Fibonacci numbers.

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

Output

Fib(1476) 13069...(299 digits)....71632.  // Exact max `double`
Fib(17127) 95902...(3569 digits)...90818.
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256