2010-10-11 4 views
4

Ok, cela semble étrange, mais j'ai besoin d'un exemple de code, qui lance EXCEPTION_FLT_UNDERFLOW. J'ai déjà du code pour gérer cette exception. Maintenant j'ai besoin d'un échantillon, qui jette cette foutue EXCEPTION_FLT_UNDERFLOW. Des conseils?C++: comment lancer EXCEPTION_FLT_UNDERFLOW?

Répondre

3

En supposant que vous voulez code réel qui déclenchera ceci:

#include <float.h> 

int main() 
{ 
    _controlfp_s(NULL, 0, _MCW_EM); // enable all floating point exceptions 

    float f= 1.0f; 

    while (f) 
    { 
     f/=2.0f; 
     // __asm fwait; // optional, if you want to trap the underflow sooner 
    } 

    return 0; 
} 
+0

MSDN m'a donné l'impression que '#pragma fenv_access (on)' était nécessaire et que le premier argument de _controlfp_s ne pouvait pas être NULL. (Y at-il un _control_fp, ou est-ce une faute de frappe pour _controlfp_s?) – zwol

+0

@Zack, c'était une faute de frappe pour _controlfp_s (...) :). Mais il compile et fonctionne directement sur vs2010. – MSN

+0

cool, cela signifie que je peux prendre la variable dummy hors de mon exemple. – zwol

2

Essayez:

RaiseException(EXCEPTION_FLT_UNDERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL); 
+0

Qu'il! Merci. – Pritorian

-2

jet EXCEPTION_FLT_UNDERFLOW;

+2

Hmm, non, AFAIK 'throw' est juste pour les exceptions C++. –

1

Même dans C99 il n'y a pas de manière portable de faire cela. Cela fonctionne sur Linux:

#define _GNU_SOURCE 
#include <fenv.h> 
int 
main(void) 
{ 
    fesetenv(FE_NOMASK_ENV); 
    feraiseexcept(FE_UNDERFLOW); 
    return 0; 
} 

mais sans #define _GNU_SOURCE et l'appel fesetenv (qui ne sont pas portables), l'exception ne sont pas jetés (== ne déclenche pas SIGFPE, en termes Unix), il a juste ensembles un drapeau. Et aucune itération de MSVC prend en charge <fenv.h>, donc vous êtes bloqué avec complètement non standard sur Windows.

Cela dit, il semble y avoir un équivalent spécifique Windows:

#include <float.h> 
#pragma fenv_access (on) 
int 
main(void) 
{ 
    _controlfp_s(0, 0, _MCW_EM); /* throw all floating point exceptions */ 
    /* trigger floating-point underflow here */ 
} 

Vous devrez provoquer une condition d'underflow en utilisant des opérations à virgule flottante réels. Je ne sais pas comment faire ça du haut de ma tête. Il serait probablement préférable de le faire à la main en langage assembleur, pour éviter les interférences du compilateur (encore plus de non-portabilité, oui, mais si vous êtes sous Windows, vous ne vous souciez probablement pas de CPU mais de x86).

+0

Un dépassement de capacité signifie simplement que vous ne pouvez pas représenter le résultat sous la forme d'un nombre à virgule flottante non dénormal. Donc, vous pouvez diviser à plusieurs reprises par une constante> 1 pour l'obtenir. – MSN