En C, sur une implémentation avec des flottants IEEE-754, quand je compare deux nombres à virgule flottante qui sont NaN, cela renvoie 0 ou "faux". Mais pourquoi deux nombres à virgule flottante qui sont tous deux inf comptent comme égaux?

Ce programme imprime "égal: ..." (au moins sous Linux AMD64 avec gcc) et à mon avis, il devrait afficher "différent: ...".

#include <stdio.h>
#include <stdlib.h>

int main(void)
  {
    volatile double a = 1e200; //use volatile to suppress compiler warnings
    volatile double b = 3e200;
    volatile double c = 1e200;
    double resA = a * c;  //resA and resB should by inf
    double resB = b * c;
    if (resA == resB)
      {   
        printf("equal: %e * %e = %e = %e = %e * %e\n",a,c,resA,resB,b,c);
      }   
    else
      {   
        printf("different: %e * %e = %e != %e = %e * %e\n", a, c, resA, resB, b, c);
      }   
    return EXIT_SUCCESS;
  }

Un autre exemple, pourquoi je pense que inf n'est pas le même que inf, est: les nombres de nombres naturels et de nombres rationnels sont tous deux infinis mais pas identiques.

Alors pourquoi inf == inf?

3
12431234123412341234123 24 janv. 2017 à 20:31

3 réponses

Meilleure réponse

Les infinis se comparent égaux parce que c'est ce que dit la norme. De la section 5.11 Détails des prédicats de comparaison:

Les opérandes infinis du même signe doivent comparer égaux.

6
nwellnhof 24 janv. 2017 à 19:17

inf==inf pour la même raison que presque tous les nombres à virgule flottante se comparent égaux à eux-mêmes: parce qu'ils sont égaux. Ils contiennent le même signe, exposant et mantisse.

Vous pensez peut-être comment NaN != NaN. Mais c'est une conséquence relativement peu importante d'un invariant beaucoup plus important: NaN != x pour any x. Comme son nom l'indique, NaN n'est pas du tout un nombre , et ne peut donc pas comparer égal à quoi que ce soit, car la comparaison en question est numérique (d'où -0 == +0) .

Il serait certainement logique que les inf se comparent de manière inégale aux autres inf, car dans un contexte mathématique, ils sont presque certainement inégaux. Mais gardez à l'esprit que l'égalité en virgule flottante n'est pas la même chose que l'égalité mathématique absolue; 0.1f * 10.0f != 1.0f et 1e100f + 1.0f == 1e100f. Tout comme les nombres à virgule flottante se transforment progressivement en dénormaux sans compromettre l'égalité la plus bonne possible, ils débordent à l'infini sans compromettre l'égalité la plus bonne possible.

Si vous voulez inf != inf, vous pouvez l'émuler: 1e400 == 3e400 évalue à vrai, mais 1e400 - 3e400 == 0 évalue à faux, car le résultat de +inf + -inf est NaN. (On pourrait sans doute dire qu'il devrait être évalué à 0, mais cela ne servirait l'intérêt de personne.)

2
Sneftel 24 janv. 2017 à 20:39

Il existe de nombreux systèmes arithmétiques. Certains d'entre eux, y compris ceux qui sont normalement couverts en mathématiques au secondaire, comme les nombres réels, n'ont pas l'infini comme nombre. D'autres ont un seul infini, par exemple la ligne réelle étendue projectivement. D'autres, comme l'arithmétique à virgule flottante IEEE en cours de discussion et la ligne réelle étendue, ont les deux l'infini positif et négatif.

L'arithmétique IEEE754 est différente de l'arithmétique des nombres réels à bien des égards, mais constitue une approximation utile à de nombreuses fins.

Il y a une logique au traitement différent des NaN et des infinis. Il est tout à fait raisonnable de dire que l'infini positif est supérieur à l'infini négatif et à tout nombre fini. Il ne serait pas raisonnable de dire quelque chose de similaire à propos de la racine carrée de -1.

0
Patricia Shanahan 25 janv. 2017 à 00:17