2010-09-22 6 views
10

J'ai g ++ 4.4.3 sur Linux avec Ubuntu Lucid Lynx, et je reçois un:Obtenir un NaN négatif sur g ++ 4.4.3, est ce standard?

-Nan

en conséquence. Sur Hardy Heron avec g ++ 4.3.1, je reçois tous les

nan

Ceci est à l'origine de mon texte régression diff à l'échec, puisque je suis en utilisant Cout pour imprimer ce résultat numérique.

Quelle est la signification d'un nan signé, et existe-t-il un moyen de dire au compilateur qu'un nan signifié est suffisant?

+0

Quel calcul faites-vous que les résultats dans une telle valeur ? –

+0

Que voulez-vous dire par "signé nan"? Voulez-vous dire négatif? Jetant un coup d'œil sur l'article de Wikipédia, les NaN sont explicitement signés. –

+4

"cout << 0./0. << endl" les résultats sont "-nan" sur tous mes systèmes Ubuntu Lucid Lynx, et "nan" sur Mac OS X Snow Leopard et Ubuntu Hardy Heron. Ce sont tous les systèmes x86_64. – Juan

Répondre

8

Vous pouvez obtenir un NaN signé depuis le NaN-ness de la valeur et le signe de la valeur sont contrôlés par différents bits IEEE754 (NaN est simplement indiquée par des valeurs d'exposant spéciales, distinctes du bit de signe). Je ne sais pas quel genre d'opération le ferait.

Il est possible que l'une des opérations normales qui produisent NaN pourrait causer une variation négative (comme +0/-0 ou +Inf/-Inf). Mais j'aurais pensé que NaNs imprimerait nan indépendamment du signe.

Cependant, bien que la norme spécifie en détail comment les nombres sont traités, il est étrangement silencieux sur la façon dont ils sont imprimés. Les listes Wikipedia page for NaN ces:

nan   NaN   NaN%  NAN   NaNQ 
NaNS  qNaN  sNaN  1.#SNAN  1.#QNAN 
-1.#IND  -NaN  NaN12345 -sNaN12300 

avec certains de ces signes montrant et la charge utile supplémentaire.

Notez que je parle ici des normes IEEE. Les normes ISO C indiquent un nombre limité de formulaires, mais le fait que le signe et/ou la charge utile soit imprimé dépend de l'implémentation. Je peux seulement supposer que les versions ultérieures de la bibliothèque ont changé leur comportement. Comment résoudre ce problème dans le compilateur, je ne suis pas sûr. Je prendrais juste l'approche pragmatique et exécuterais votre dossier de sortie par quelque chose comme sed 's/-nan/nan/g'. J'espère que cela ne va pas introduire d'autres problèmes.

Et vous devriez également garder un œil sur le formulaire qui permet l'impression de la charge utile, bien que je ne m'inquiète que lorsque les tests commencent à échouer à nouveau. Mais j'ai placé un commentaire quelque part près de cette commande sed indiquant que cela pourrait arriver à un moment donné dans le futur. De cette façon, au moins le gars qui vous suit comprendra pourquoi.

+0

Je peux filtrer le résultat, mais je veux juste m'assurer que mon raisonnement est légitime quand quelqu'un voit le filtrage. – Juan

+0

La norme elle-même le définit comme NaN lorsque exponent est la valeur max et mantisse est d'un certain format. Le signe n'entre pas dedans. Je voudrais simplement craie jusqu'à la routine de sortie simpliste qui a vérifié le signe indépendamment du fait qu'il produisait un nombre réel ou l'un des spéciaux. – paxdiablo

2

Signé NaN est possible, bien que je ne connaisse pas assez le point flottant pour savoir pourquoi une plate-forme produirait -NaN et une autre produirait NaN. Mais comme NaN a des comportements inhabituels, je ne suis vraiment pas surpris que cela puisse arriver.

Voici un extrait de la description du document C99 pour le point Floating formaté E/S:

Un argument de type double représentant un NaN est converti en un des styles [-] nan ou [-] nan (n-char-sequence) - quel style, et la signification de toute séquence n-char, est définie par l'implémentation.Le spécificateur de conversion F

Vous pouvez utiliser copysign() pour obtenir le signe d'une valeur NaN. Un exemple du document C99:

if (isnan(c)) c = copysign(0.0, c); 

Mais as paxdiablo indicated, il pourrait être plus facile de permettre le résultat « -Nan » dans vos scripts de test.

13

Le changement de comportement peut être dû aux bibliothèques plutôt qu'au compilateur. Il y a certainement un changement de glibc autour de la bonne sorte de temps - de l'entrée pour 2009-08-23 à la ligne 2528 dans ChangeLog.17 dans la source glibc:

... 
    * stdio-common/printf_fp.c: ISO C expects to print the sign of NaN 
    as well. 
... 
+1

Une trouvaille incroyable. Le même binaire copié sur la machine la plus récente donne le -nan. Excellent travail! – Juan

+2

En fait, ISO C ne m'attend pas à imprimer le signe, il dépend de l'implémentation. Ne me laissez pas détourner votre réponse, c'était une bonne découverte, et sans doute la raison pour laquelle le comportement a changé. – paxdiablo

+0

Matthew Slattery Comment avez-vous réussi à trouver cette ligne qui était tout à fait indiscutable? – Bilow

Questions connexes