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.
Possible duplicata de [C IEEE-Floats inf égal inf] (http://stackoverflow.com/questions/41834621/c-ieee-floats-inf-equal-inf) –
@ 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
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.) –