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
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;
}
Essayez:
RaiseException(EXCEPTION_FLT_UNDERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
Qu'il! Merci. – Pritorian
jet EXCEPTION_FLT_UNDERFLOW;
Hmm, non, AFAIK 'throw' est juste pour les exceptions C++. –
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).
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
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
@Zack, c'était une faute de frappe pour _controlfp_s (...) :). Mais il compile et fonctionne directement sur vs2010. – MSN
cool, cela signifie que je peux prendre la variable dummy hors de mon exemple. – zwol