views:

77

answers:

4

Ok, it sounds strange, but I need a sample code, that throws EXCEPTION_FLT_UNDERFLOW. I already have code to handle that exception. Now I need sample, that throws this damn EXCEPTION_FLT_UNDERFLOW. Any advises?

+3  A: 

Try:

RaiseException(EXCEPTION_FLT_UNDERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
Shay Erlichmen
That it! Thanks.
Pritorian
A: 

throw EXCEPTION_FLT_UNDERFLOW;

rturrado
Hmm, no, AFAIK `throw` is just for C++ exceptions.
Matteo Italia
+1  A: 

Even in C99 there is no portable way to do this. This works on Linux:

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

but without the #define _GNU_SOURCE and the fesetenv call (which are not portable), the exception is not thrown (== does not trigger SIGFPE, in Unix terms), it just sets a flag. And no iteration of MSVC supports <fenv.h>, so you're stuck with completely nonstandard on Windows.

That said, there does appear to be a Windows-specific equivalent:

#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 */
}

You will have to cause an underflow condition using actual floating point operations. I don't know how to do that off the top of my head. It would probably be best to do it by hand in assembly language, to avoid interference from the compiler (even more non-portability, yes, but if you're on Windows you probably don't care about any CPU but x86).

Zack
Underflow just means you can't represent the result as a non-denormal floating point number. So you can repeatedly divide by some constant > 1 to get it.
MSN
+1  A: 

Assuming you want actual code that will trigger this:

#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;
}
MSN
MSDN gave me the impression that `#pragma fenv_access(on)` was necessary and that the first argument to _controlfp_s could not be NULL. (Is there a _control_fp, or is that a typo for _controlfp_s?)
Zack
@Zack, that was a typo for _controlfp_s(...) :). But it compiles and runs on vs2010 directly.
MSN
cool, that means I can take the dummy variable out of my example.
Zack