2017-01-31 1 views
1

Lorsque vous avez une implémentation en virgule flottante conforme à IEEE754, toute comparaison avec un NaN est false, même NaN == NaN, mais +inf == +inf est true, pourquoi?Quelle est la raison d'être inf == inf dans IEEE754

De mon point de vue, il serait plus logique de dire +inf == +inf est faux, raisons:

  • Le nombre de nombres naturels et des nombres rationnels, les deux sont infinis, mais pas la même chose.

  • Si vous avez X=1e200 et Y=1e300 (les deux, X et Y sont 64 bits double), donc x==y est false, mais x*1e200==y*1e200 est vrai true (les deux sont + inf), qui est mathématique incorrecte.

  • Il existe déjà un traitement spécial nécessaire, pour NaN, où X==X est false, donc il n'y aura pas beaucoup plus de complexité de mise en œuvre pour mettre en œuvre ce +inf == +inf retour false. Peut-être même moins, car inf et NaN nous le même "exposant". Je ne vois aucun avantage, ou aucune application qui nécessite le fait que +inf == +inf. De toute façon, vous ne devriez pas comparer les valeurs à virgule flottante avec ==.

  • X==Y est generel alors true, si X-Y==0 est true, mais inf-inf est NaN.

Modifier

Comme nwellnhof allready a écrit: La question liée: C IEEE-Floats inf equal inf, est pas la même, il y avait la question "pourquoi la mise en œuvre de la langue de cette façon?", Voici la question " Pourquoi la norme est-elle définie de cette façon? ". (Et ces deux questions sont du même utilisateur)

+1

Possible duplicata de [C IEEE-Floats inf égal inf] (http://stackoverflow.com/questions/41834621/c-ieee-floats-inf-equal-inf) –

+1

@ LưuVĩnhPhúc Comme je l'ai noté dans ma réponse à la question liée, je pense que ce n'est pas un doublon. (* Pourquoi mon code ne fait-il pas ce que j'attends * vs * Pourquoi la norme ne définit-elle pas ce que j'attends *.) – nwellnhof

+0

Dans votre première raison, vous semblez confondre des cardinalités d'ensembles infinis avec des points sur le réel étendu ligne. Les deux sont appelés "infini", mais ils n'ont vraiment rien à voir l'un avec l'autre. (Et BTW, la cardinalité de l'ensemble des nombres naturels * est * la même que celle de l'ensemble des nombres rationnels.) –

Répondre

2

Vous auriez probablement demander William Kahan, le principal architecte derrière IEEE 754-1985, mais this answer jette un peu de lumière sur le sujet:

plus important , il n'y avait pas de prédicat isnan() au moment où NaN a été formalisé dans l'arithmétique 8087; Il était nécessaire de fournir aux programmeurs un moyen pratique et efficace de détecter les valeurs NaN qui ne dépendaient pas de langages de programmation fournissant quelque chose comme isnan(), ce qui pourrait prendre de nombreuses années. Je citerai la propre écriture de Kahan sur le sujet:

S'il n'y avait pas moyen de se débarrasser des NaN, ils seraient aussi inutiles qu'indéfinis sur les CRAY; dès qu'il en a été question, il vaut mieux arrêter le calcul plutôt que de le poursuivre indéfiniment jusqu'à une conclusion indéfinie. C'est pourquoi certaines opérations sur les NaN doivent fournir des résultats non-NaN. Quelles opérations? ... Les exceptions sont les prédicats C "x == x" et "x!= x ", qui sont respectivement 1 et 0 pour chaque nombre infini ou fini x [emphase ajoutée] mais inverse si x n'est pas un nombre (NaN); ceux-ci fournissent la seule distinction non exceptionnelle simple entre NaNs et les nombres [emphase ajoutée] dans les langues qui manquent un mot pour NaN et un prédicat IsNaN (x).

Si +inf était pas égal à +inf, le test x != x pour NaN ne fonctionnerait pas parce qu'il attraperait infinités aussi bien. En 1985, un programmeur C aurait pu écrire:

#define is_nan(x)  ((x) != (x)) 
#define is_pos_inf(x) ((x) == 1.0/0.0) 
#define is_neg_inf(x) ((x) == -1.0/0.0) 

Avec inf != inf, vous auriez besoin de quelque chose comme:

#define is_nan(x)  (!((x) >= 0) && !((x) <= 0)) 
#define is_pos_inf(x) ((x) != (x) && (x) > 0.0) 
#define is_neg_inf(x) ((x) != (x) && (x) < 0.0) 

Je peux voir votre point et je suis d'accord que d'avoir +inf != +inf est plus correct de un point de vue purement mathématique. Mais à l'OMI, cela ne l'emporte pas sur les considérations pratiques. Les [ensembles] de nombres naturels et de nombres rationnels sont tous les deux infinis mais [n'ont] pas la même [cardinalité].

Cela n'a pas grand-chose à voir avec les calculs en virgule flottante.

Si vous avez X = 1e200 et Y = 1e300 (les deux, X et Y sont 64 bits double), donc x == y est faux, mais x * y * 1e200 == 1e200 est vrai vrai (les deux sont + inf), ce qui est mathématique incorrect.

Les mathématiques à virgule flottante sont intrinsèquement incorrectes mathématiquement. Vous pouvez trouver beaucoup fini nombres à virgule flottante, X, , Z, avec X != Y, où X <op> Z == Y <op> Z.

Je ne vois aucun avantage, ni aucune application qui nécessite le fait que + inf == + inf. Vous ne devriez pas comparer les valeurs à virgule flottante avec == de toute façon. Je ne peux pas non plus voir une application qui exigerait +inf != +inf.

X == Y est vrai, si X-Y == 0 est vrai, mais inf-inf est NaN.

Il s'agit en fait d'une incohérence que +inf != +inf résoudrait. Mais cela me semble un détail mineur.

+1

Vous utilisez encore 'définir is_nan (x) (((x)! = (X)) && !((x) <0) && !((x)> 0)) ', (+ inf serait toujours supérieur à 0 et -inf encore inférieur à 0) même lorsque' inf + = + inf' – 12431234123412341234123

+0

Ou plus court: 'define is_nan (x) (! ((x) <= 0) &&! ((x) => 0)) ' – 12431234123412341234123

+0

@ 12431234123412341234123 Voir ma réponse modifiée. – nwellnhof