web-dev-qa-db-fra.com

Pourquoi NaN existe?

Je ne demande pas "pourquoi ce calcul donne-t-il NaN", je demande "Pourquoi NaN existe-t-il du tout, plutôt que de provoquer une exception ou une erreur?"

Je me le demande depuis un moment et j'en ai discuté avec les gens de temps à autre. 

Les seules réponses que j'ai obtenues sont "Eh bien, vous ne voulez pas essayer d'attraper chaque différence, n'est-ce pas?" ou "Il existe des scénarios dans lesquels NaN est un résultat valide".

Cela étant dit, je n'ai jamais reçu d'exemple concret de NaN comme résultat valable. En supposant que NaN ne puisse jamais être un résultat valide, je ne comprends pas pourquoi il existe du tout. Si cela se produit, à ma connaissance, vous avez un bug. Période. 

Vous voulez que le programme plante et meure alors et là, de sorte que vous puissiez facilement trouver où il a mal tourné. Ceci plutôt que de laisser le programme se déchaîner, peut-être écrire des données corrompues, éventuellement envoyer des données corrompues, ou faire toutes sortes de choses désagréables - avant d’évoluer inévitablement. (Comme dit dans "Le programmeur pragmatique" - Crash, Don't Trash ")

Maintenant, je crois que les concepteurs IEEE 754 étaient beaucoup plus intelligents que moi, ce qui me porte à croire qu'il DOIT y avoir une raison pour son existence. Quelle est cette raison?

7
Harald Kanin

Chaque fois que j'écris quelque chose à propos de maths, j'ai peur d'être assommé par un vrai mathématicien avec une barre de métal, mais voilà, nous allons affronter nos peurs:

"Pourquoi NaN existe-t-il plutôt que de provoquer une exception ou une erreur?"

Parce que ce n'est ni une exception ni une erreur. C'est un résultat parfaitement valable pour un calcul. Vous avez plusieurs cas d'utilisation en mathématiques où vous recevez l'équivalent de "NaN", c'est-à-dire quelque chose qui ne peut pas être mesuré. Pensez au calcul d'une intersection entre deux lignes parallèles. Ou le calcul de la masse d'un photon

Dans ces cas, où vous allez chercher "le côté mathématique de la vie" dans votre code (j'imagine que cela s'applique principalement aux logiciels scientifiques), nous avons la situation suivante:

  • Ils ne font pas d'erreur, les variables ont les valeurs dont elles ont besoin, les calculs ont été effectués et voici le résultat. Malheureusement, pas un nombre réel (Un nombre complexe peut-être? Peut-être une indétermination qui peut être résolue en utilisant d'autres méthodes mathématiques?), Vous avez toujours la réponse au calcul.
  • Ils ne font pas exception, votre code ne va pas mal, ce n’est pas une anomalie, c’est la réponse: "NaN" (où vous en attendiez 42?). Inutile d’arrêter ici le flux de votre programme: informez l’utilisateur que le calcul n’a pas de solution ou qu’il n’est pas déterminé, et qu’il en soit content (note: je mente un peu paragraphe). 

Vous voulez que le programme plante et meure alors et là afin que vous puissiez trouver facilement où il a mal tourné.

Vous avez tout à fait raison: vous pouvez toujours le traiter comme une exception ou comme une erreur si le concept de NaN n’est pas un résultat valable dans le contexte de votre programme .Imagine calculant le diamètre nécessaire d’une colonne pour un stade de football et obtenir NaN. Ugh ... ce serait sûrement une erreur, je veux construire ce stade, donne-moi un diamètre !. Vous avez également totalement tort: ​​s'il vous plaît, ne dites pas que vous trouverez "facilement" où il y a eu une erreur simplement parce que vous déclenchez une exception après NaN. Je connaissais certaines personnes en train de déboguer des modèles météorologiques qui aimeraient avoir un mot avec vous (ces équations ne sont pas amusantes).

Vous avez actuellement de nombreuses bibliothèques et implémentations qui prennent des décisions éclairées sur ce que sont des erreurs, quelles sont les exceptions, etc. Les concepteurs IEEE vous ont laissé la décision. Et les codeurs de langue vous ont transmis ce pouvoir. Fais-en bon usage.

Et si vous lisez jusqu'à ici, laissez-moi vous dire que je vous mentais un peu par souci de simplification excessive. Le couplage IEEE définit deux types de NaN, le silencieux et le signaleur. J'ai parlé des plus calmes, des gentils. Les signaleurs provoqueront des exceptions dans votre logiciel (débordement, débordement, etc.).

1
Moreno