2010-09-01 3 views
28

Je vais faire des calculs mathématiques en C++. Le nombre à virgule flottante d'entrée est un nombre valide, mais après les calculs, la valeur résultante est NaN. Je voudrais tracer le point où la valeur NaN apparaît (éventuellement en utilisant GDB), au lieu d'insérer beaucoup de isNan() dans le code. Mais j'ai trouvé que même un code comme celui-ci ne déclenchera pas d'exception quand une valeur NaN apparaît.Comment tracer un NaN en C++

double dirty = 0.0; 
double nanvalue = 0.0/dirty; 

Quelqu'un pourrait-il proposer une méthode pour tracer NAN ou transformer un NaN en une exception?

+0

connexes: [? Puis-je faire gcc me dire quand un résultat de calcul NaN ou inf lors de l'exécution] (http://stackoverflow.com/questions/2941611/can-i-make-gcc-tell-me-when -a-calcul sur les résultats-en-nan-ou-inf-à-runtime/20973509) – legends2k

+0

également http://stackoverflow.com/questions/5393997/stopping-the-debugger-when-a-nan-floating-point -Nombre-est-Produced – Riot

Répondre

7

Dans Visual Studio, vous pouvez utiliser la fonction _controlfp pour définir le comportement de calculs à virgule flottante (voir http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx). Peut-être qu'il existe une variante similaire pour votre plate-forme.

+0

Salut, merci pour votre réponse. Malheureusement, ma plate-forme est GCC4.1, Centos 5.5 Linux. J'essaie toujours de comprendre comment réaliser la même chose sous Linux avec GCC – user1492900

+2

feenableexcept() semble fonctionner, j'essaie maintenant de tracer mon programme avec ceci. http://gcc.gnu.org/onlinedocs/gcc-3.1.1/g77/Floating-point-Exception-Handling.html # Floating-point% 20Exception% 20Handling – user1492900

0

On peut permettre que l'on appelle « signalisation NaN ». Cela devrait permettre facilement au débogueur de trouver la bonne position.

Via google, je trouve cela pour permettre NaN de signalisation en C++, aucune idée si cela fonctionne:

std::numeric_limits::signaling_NaN();

Usefulness of signaling NaN?

+2

cette expression évalue à une NAN de signalisation, mais je pense que pagedown est plus intéressé à forcer une exception à virgule flottante pour les opérations qui renvoient NaN, ce qui serait probablement une option de compilateur spécifique à la plateforme ou la configuration d'exécution du Processeur FP. –

+0

Ah pardon. Je l'ai compris comme faisant toute la signalisation NaN. –

+0

Merci beaucoup. Je vais regarder les options du compilateur :) – user1492900

35

Puisque vous évoquez avec gdb, voici une solution qui fonctionne avec gcc - vous voulez que les fonctions définies dans fenv.h:

#include <fenv.h> 
#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    double dirty = 0.0; 

    feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT); // Enable all floating point exceptions but FE_INEXACT 
    double nanval=0.0/dirty; 
    printf("Succeeded! dirty=%lf, nanval=%lf\n",dirty,nanval); 
} 

l'exécution du programme ci-dessus produit la sortie « exception à virgule flottante ». Sans l'appel à feenableexcept, le "Succeeded!" le message est imprimé.

Si vous écrivez un gestionnaire de signal pour SIGFPE, cela peut être un bon endroit pour définir un point d'arrêt et obtenir le retraçage que vous voulez. (Décharge: ne l'avez pas essayé!)

+0

Merci beaucoup – user1492900

+2

Le bug est trouvé :) – user1492900

+13

Merci pour cette réponse, je tiens juste à souligner que l'activation de * toutes * les exceptions à virgule flottante permet aussi FE_INEXACT ce qui arrive très souvent (même pour: float f = 0.1) et le débogage devient impossible. Il est préférable d'utiliser feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); – DarioP

1

Quelques notes sur la programmation en virgule flottante peuvent être trouvées sur http://ds9a.nl/fp/ en incluant la différence entre 1/0 et 1.0/0 etc, et ce qu'est un NaN et comment il agit.

+0

Merci beaucoup – user1492900

Questions connexes