Question

Après avoir examiné une autre question sur SO ( utiliser NaN en C ++ ), je suis devenu curieux de savoir std::numeric_limits<double>::signaling_NaN().

Je ne pouvais pas obtenir que signalant_NaN lève une exception. Je pensais que peut-être, en signalant que c’était vraiment un signal, j’ai donc essayé d’attraper SIGFPE, mais non…

Voici mon code:

double my_nan = numeric_limits<double>::signaling_NaN();
my_nan++;
my_nan += 5;
my_nan = my_nan / 10;
my_nan = 15 / my_nan;
cout << my_nan << endl;

numeric_limits<double>::has_signaling_NaN est évalué à true, il est donc implémenté sur mon système.

Des idées?

J'utilise le compilateur C ++ de ms visual studio .net 2003. Je veux tester sur un autre quand je rentre à la maison.

Merci!

Était-ce utile?

La solution

Vous pouvez utiliser la fonction _control87() pour activer la navigation flottante. point des exceptions. Dans la documentation MSDN sur signal():

  

Remarque:

     

Les bibliothèques d'exécution masquent toutes les exceptions en virgule flottante par défaut.

Lorsque les exceptions en virgule flottante sont activées, vous pouvez utiliser <=> ou SEH (gestion d'exception structurée) à prendre eux.

Autres conseils

Un mot d'avertissement: L'utilisation de DLL tierces peut activer ces exceptions en mode silencieux. Cela est particulièrement vrai pour les DLL de chargement écrites dans un langage qui les active par défaut.

Cela s'est produit dans deux cas: impression d'un contrôle de navigateur intégré sur une imprimante HP et enregistrement de ma DLL (qui définit certaines valeurs initiales sur NaN) à partir d'InnoSetup, qui est écrit en Delphi.

La clé réside dans numeric_limits<T>::has_signaling_NaN . Quelle valeur cela a-t-il pour vous? (Le MSDN semble suggérer que c'est toujours false pour MSVC?)

De TFM :

cout << "The signaling NaN for type float is:  "
    << numeric_limits<float>::signaling_NaN( )
    << endl;

- >

  

Le NaN de signalisation pour le type float est: 1. # QNAN

où «Q» signifie «silencieux». Je ne sais pas pourquoi il renverrait cela, mais c'est pourquoi il ne lève pas une exception pour vous.

Par curiosité, cela fonctionne-t-il mieux?

const double &real_snan( void )
{
    static const long long snan = 0x7ff0000080000001LL;
    return *(double*)&snan;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top