J'ai été membre de l'IEEE-754 comité, je vais essayer de clarifier un peu les choses.
Tout d'abord, les nombres à virgule flottante ne sont pas des nombres réels, et l'arithmétique en virgule flottante n'a pas satisfait les axiomes de l'arithmétique réelle. Trichotomie n'est pas la seule propriété de l'arithmétique réelle qui ne fonctionne pas pour les chars, ni même le plus important. Par exemple:
- L'Addition est associative.
- La loi de distributivité ne tient pas.
- Il y a des nombres à virgule flottante sans inverses.
Je pourrais continuer. Il n'est pas possible de spécifier une taille fixe de l'arithmétique type qui satisfait toutes les propriétés de l'arithmétique réelle que nous connaissons et aimons. 754 comité doit décider de plier ou de casser quelques-uns d'entre eux. C'est guidé par une jolie principes simples:
- Lorsque nous le pouvons, nous faisons correspondre le comportement de l'arithmétique réelle.
- Quand nous ne le pouvons, nous essayons de rendre les violations prévisible et facile à diagnostiquer que possible.
Concernant votre commentaire "cela ne veut pas dire que la bonne réponse est "faux", c'est faux. Le prédicat (y < x)
demande si y
est inférieure à x
. Si y
est NaN, il est pas inférieure à toute valeur à virgule flottante x
, donc la réponse est nécessairement faux.
Je l'ai mentionné que trichotomie ne fonctionne pas pour les valeurs à virgule flottante. Cependant, il est une propriété qui ne maintenez-la enfoncée. La Clause 5.11, alinéa 2, de la 754-2008 standard:
Quatre mutuellement exclusifs relations sont possibles: inférieur à, égal à, supérieur à, et non ordonnée. Le dernier cas de figure se présente lorsque au moins un des opérandes est NaN. Chaque NaN compare non ordonnée avec tout, y compris lui-même.
Aussi loin que d'écrire du code supplémentaire pour gérer les NaNs va, il est généralement possible (bien que pas toujours facile) à la structure de votre code de telle façon que NaNs automne correctement, mais ce n'est pas toujours le cas. Quand il n'est pas certain code supplémentaire peut être nécessaire, mais c'est un petit prix à payer pour la commodité qui algébrique fermeture apporté à l'arithmétique en virgule flottante.
Addendum:
De nombreux commentateurs ont fait valoir qu'il serait plus utile pour préserver la réflexivité, de l'égalité et de la trichotomie au motif que l'adoption NaN != NaN ne semble pas pour préserver le familier axiome. J'avoue avoir une certaine sympathie pour ce point de vue, alors j'ai pensé que je voudrais revoir cette réponse et de fournir un peu plus de contexte.
Ma compréhension de parler à Kahan est que NaN != NaN né de deux considérations pragmatiques:
qu' x == y
doit être équivalent à x - y == 0
chaque fois que possible (au-delà d'être un théorème d'arithmétique réelle, ce qui rend le matériel de mise en œuvre de comparaison plus efficace en terme d'espace, ce qui était de la plus haute importance au moment de la norme a été élaborée note, cependant, que c'est violée pour x = y = infini, il n'est donc pas une bonne raison; il pouvait raisonnablement tordue x - y == 0 or NaN
).
plus important encore, il n'y avait pas isnan( )
prédicat au moment de la NaN a été formalisé dans la 8087 l'arithmétique; il était nécessaire de fournir des programmeurs avec un pratique et efficace des moyens de détection NaN valeurs qui ne dépendent pas des langages de programmation offrant quelque chose comme isnan( )
qui pourrait prendre de nombreuses années. Je vais vous citer Kahan propre écriture sur le sujet:
Ont été il y a pas moyen de se débarrasser de NaNs, ils seraient aussi inutile que Indefinites sur les CRAYs; dès que l'on s'étaient rencontrés, le calcul serait le meilleur arrêté plutôt que de suite pour une durée indéterminée à durée Indéterminée conclusion. C'est pourquoi certaines opérations sur NaNs doit fournir non-NaN résultats. Quelles opérations? ... À l'exception de C prédicats "x == x" et " x != x ", qui sont respectivement 1 et 0 pour chaque infinie ou finie nombre x mais à l'inverse si x n'est Pas un Nombre ( NaN ); elles constituent l'unique simple, rien d'exceptionnel distinction entre NaNs et des numéros dans des langues qui n'ont pas de mot pour NaN et d'un prédicat IsNaN(x).
Notez que c'est également la logique qui exclut le retour à quelque chose comme un "Pas-A-Booléen". Peut-être que ce pragmatisme a été égaré, et le standard aurait exigé isnan( )
, mais qui aurait fait NaN presque impossible de l'utiliser, efficace et pratique pour plusieurs années, tout le monde attendait pour le langage de programmation de l'adoption. Je ne suis pas convaincu que cela aurait été un compromis raisonnable.
Pour être clair: le résultat de NaN == NaN ne va pas changer maintenant. Mieux vaut apprendre à vivre avec elle que de se plaindre sur internet. Si vous voulez faire valoir qu'un ordre de relation adapté pour les conteneurs doit également exister, je vous conseille de plaider pour que votre langage de programmation favori de mettre en œuvre l' totalOrder
prédicat normalisée la norme IEEE-754 (2008). Le fait qu'il n'a pas parle déjà de la validité de Kahan est une préoccupation qui a motivé l'état actuel des choses.