cx86floating-pointunderflow

How can an underflow lead to an overflow?


I'm reading the Intel Manual (Intel® 64 and IA-32 Architectures Software Developer Manuals *2016) and am curious if I understand this one excerpt correctly about the need for an Underflow Exception:

The ability to detect and handle underflow is provided to prevent a very small result from propagating through a computation and causing another exception (such as overflow during division) to be generated at a later time.

-Section 4.9.1.5

So my question is what would this scenario look like? Could one possible pseudocode computation be

veryVerySmallNumber = SmallestFloatpossible -1
veryVeryLargeNumber = BigBigFloat
answer = veryVerySmallNumber / veryVeryLargeNumber

I read there are two ways the processor can handle this but I'm more concerned with HOW an underflow could lead to an overflow. I'd also appreciate any clarification on the general spirit of handling these scenarios.


Solution

  • The Intel reference to underflow is about floating-point operations.

    This program:

    #include <stdio.h>
    
    int main(void)
    {
        float x = 0x1.23456p-70f;   //  Set x to a number around 2**-70.
        float y = x*x;
        float z = 1/y;
        printf("x = %g.\n", x);
        printf("y = %g.\n", y);
        printf("z = %g.\n", z);
    }   
    

    in common C implementations that use IEEE-754 binary32 for float prints:

    x = 9.63735e-22.
    y = 9.29061e-43.
    z = inf.
    

    In x*x, the computation underflows—the result is in the subnormal range, where the float format cannot represent it with full precision (and, in particular, some of the value of the result is lost while rounding it to fit into the format).

    Then, because the number is so small, attempting to take its reciprocal fails to produce a finite result—the result is out of the float range of finite numbers, so it produces infinity. The operation is said to overflow.

    Intel hardware provides a means to detect underflow: with FP exceptions unmasked, the underflow exception will actually trap (e.g. on Linux/Unix, the OS will deliver a SIGFPE floating point exception). Or with FP exceptions masked like normal, it will just set a sticky flag bit in MXCSR to record that an underflow exception happened since that last time exception status flags were zeroed. There are other exception flags for overflow, inexact (non-zero rounding error), invalid (NaN result). See a table of the MXCSR bits, or look in the Intel x86 manuals. There are similar separate masked-exception recording flags for legacy x87.

    A program can take advantage of this by detecting the underflow in x*x and performing whatever steps it wants to avoid losing track of the value completely in later operations.