2009-02-22 33 views
2

Je voudrais gérer exception FPU sur les fenêtres, quelque chose comme:Manipulation exception FPU sur les fenêtres

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

int main() 
{ 
    double b = 0; 
    int raised; 
    feclearexcept (FE_ALL_EXCEPT); 
    b /= 0; 
    raised = fetestexcept (FE_OVERFLOW | FE_INVALID); 
    if (raised & FE_OVERFLOW) { printf("over\n");} 
    if (raised & FE_INVALID) { printf("invalid\n");} 

    return 0; 
} 

Mais sur les fenêtres. J'ai essayé de lire le MSDN, mais le document n'est pas clair du tout. Je veux le faire avec les compilateurs Visual Studio, sur les architectures x86 et amd64.

Je ne suis pas intéressé par la traduction de l'exception en C++ - en fait, je ne suis même pas intéressé par l'exception FPU, seulement en connaissant l'état FPU après un calcul, comme l'exemple ci-dessus.

modifier == ==

Ok, on dirait qu'il est en fait beaucoup plus simple: en utilisant _clearfp suffit:

#include <math.h> 
#include <float.h> 
#include <stdio.h> 

int main() 
{ 
    double b = 0; 
    int raised; 
    raised = _clearfp(); 
    b /= 0; 
    raised = _clearfp(); 
    if (raised & SW_INVALID) { printf("invalid\n");} 

    return 0; 
} 

beaucoup mieux que de traiter avec des exceptions, SEH et d'autres choses non portable:

+0

Works dans G ++ sous Windows, semble être une erreur de compilation. – schnaader

+0

Oui, gérer "sur Windows" n'est pas précis: je voulais dire avec Visual Studio. –

Répondre

2

Vous pouvez utiliser _statusfp2() pour récupérer le statut de virgule flottante. Méfiez-vous que 32 bits utilise à la fois les instructions FPU et SSE. Un exemple de code:

#include "stdafx.h" 
#include <float.h> 
#include <math.h> 
#include <assert.h> 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    unsigned x86; 
    unsigned sse; 
    // Test zero-divide 
    double d = 0; 
    double v = 1/d; 
    _statusfp2(&x86, &sse); 
    assert(x86 & _EM_ZERODIVIDE); 
    // Test overflow 
    v = pow(10, 310.0); 
    _statusfp2(&x86, &sse); 
    assert(sse & _EM_OVERFLOW); 
    return 0; 
} 
+0

merci, c'est exactement ce que je cherchais. –

0

Ces fonctions sont obligatoires selon la norme, vous ne devriez donc pas avoir de problème de portage. Quelle erreur exacte frappez-vous?

+0

Il ne compile même pas - AFAIK, MS compilateurs n'ont pas fenv.h, mais ont leur propre mécanisme. –

+0

Pour VS, vous devez compter sur le pragma arul mentionné. – dirkgently

2

Si c'est Visual Studio, essayez de mettre dans cette ligne:

#pragma float_control (except, on) 

En savoir plus sur cette here et here.

EDIT:

Si vous voulez faire cela en C ordinaire, vous aurez besoin de jeter un oeil à la structured exception handling (SEH).

+0

Les deux liens sont extrêmement peu clairs, malheureusement; Je ne comprends pas ce que float_control est censé faire: traduire l'erreur en exception C++? Je voudrais une solution C pure. –