2
votes

Comment traiter la valeur de retour inf

Je travaille seul sur un livre sur C. Ce n'est pas un devoir à rendre. J'écris un programme C pour déterminer le plus grand nombre de Fibonacci que ma machine peut produire. Et chargé d'utiliser une méthode non récursive.

Mon code:

if (value == inf)
  break;

Le code fonctionne bien, mais je veux interrompre lorsque la sortie me donne la première instance de:

For 17127 the value of the fibonacci series = inf


5 commentaires

Cette boucle dans la fonction main , quand est-elle censée se terminer? Si vous voulez ajouter une condition spéciale qui casser la boucle, pourquoi avoir une boucle conditionnelle quand même? Surtout celui qui pourrait conduire à un débordement arithmétique d'entiers signés (qui est comportement indéfini ).


Ce n'est pas. On laisse volontairement l'infini pour voir la taille des nombres. J'espère pouvoir l'arrêter lorsqu'une valeur particulière apparaît


C'est seulement infini en théorie. En pratique, toutes les valeurs entières sur un ordinateur sont limitées. Et comme mentionné, le débordement arithmétique d'entiers signés (qui se produira avec n ++ lorsque vous franchissez la limite de int ) en C conduit à un comportement indéfini.


vous devriez probablement au moins vérifier man (3) isinf () et fpclassify (), inf n'est pas destiné à être utilisé comme dans votre code.


Assez facile pour mettre des chiffres et l'arrêter. Ça ira. Merci


4 Réponses :


4
votes

Le plus simple est d'utiliser INFINITY ou isinf () .


0 commentaires

1
votes

le plus grand nombre de Fibonacci que ma machine peut produire

Cette question ne concerne aucun type de données mais elle concerne machine

La règle de base de fibonacci est la suivante:

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

Vous pouvez prendre une variable unsigned long long de grande taille et vous pouvez continuer à l'ajouter. Mais que faire si ce type de données est débordé? Vous n'êtes pas concerné par le type de données. Votre machine peut produire un nombre encore plus grand que le long long . Quel serait ce nombre? Des bits entiers sur la RAM? Disque dur?

Puisque vous devez utiliser une méthode itérative et non une méthode récursive, votre enseignant / livre / instructeur peut vous tester sur des boucles (et non sur une API standard). Voici un exemple de code utilisant 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;

}

Sortie:

12200160415121876738 p>


0 commentaires

2
votes

Je viens de faire une petite recherche et j'ai trouvé cette belle astuce:

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

Eh bien, il s'avère que ce qui se passe est lorsque la température atteint Inf la condition if temp - temp produit Nan qui n'équivaut à rien et le reste exécute simplement break; pour quitter le processus.


2 commentaires

L'explication est fausse. Cela fonctionne parce que Inf - Inf produit Nan , qui est différent de tout, y compris lui-même.


@AlexeyFrunze il s'avère que vous avez raison, il n'est pas nécessaire de typer l'un des temp s. Une condition if comme (temp - temp! = 0) ou juste (temp - temp! = Any_number) semble faire le travail puisque tous produisent Nan .



1
votes

Je veux interrompre lorsque la sortie me donne la première instance de: inf

Testez simplement INFINITY depuis . Le résultat ne sera pas un exact numéro de Fibonacci . P >

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

Sortie

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

long double

Utilisez le type à virgule flottante le plus large et recherchez une addition inexacte.

12200160415121876738

Sortie

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

Entiers

Utilisez le type le plus large disponible. Cela s'apparente à l'approche @ Syed.Waris unsigned long long . Bien qu'il soit courant que unsigned long long et uintmax_t aient la même plage, l'utilisation de uintmax_t assure la plus large.

uintmax_t : Le type suivant désigne un type entier non signé capable de représenter n'importe quelle valeur de n'importe quel type entier non signé:

12200160415121876738

Output

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

String

Une alternative à double ou un type int , consiste à créer une simple fonction string add str_add () , alors il est assez facile de former des grands nombres de Fibonacci.

1.306989e+308

Sortie

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

0 commentaires