Using the Floating Point Exception Handling (-fpe) Option

The Fortran compiler supports several kinds of floating-point exceptions; a summary of their masked (or default) responses is given below:

For example,  in round-to-nearest mode 1E30 * 1E30 overflows the single-precision floating-point range and results in a +Infinity;  -1E30 * 1E30 results in a -Infinity.

The -fpen option allows some control over the results of floating-point exceptions.

-fpe0 restricts floating-point exceptions as follows:

This options sets -IPF_fp_speculationstrict  if no specific -IPF_fp_speculation option is specified.

-fpe1 restricts only floating-point underflow:

If a floating-point underflow occurs, the result is set to zero and execution continues.

-fpe3, the default, allows full floating-point exception behavior:

Floating underflow is gradual:  denormalized values are produced until the result becomes 0.

The -fpe option affects the Fortran main program only.  The floating-point exception behavior set by the Fortran main program remains in effect throughout the execution of the entire program unless changed by the programmer. If the main program is not Fortran, the user can use the Fortran intrinsic FOR_SET_FPE to set the floating-point exception behavior.

When compiling different routines in a program separately, you should use the same value of n in -fpen.

An example follows:

       IMPLICIT NONE

       real*4 res_uflow, res_oflow

       real*4 res_dbyz, res_inv

       real*4 small, big, zero, scale

       small = 1.0e-30

       big   = 1.0e30

       zero  = 0.0

       scale = 1.0e-10

!      IEEE underflow condition (Underflow Raised)

       res_uflow = small * scale

       write(6,100)"Underflow: ",small, " *", scale, " = ", res_uflow

!      IEEE overflow condition (Overflow Raised)

       res_oflow = big * big

       write(6,100)"Overflow: ", big, " *", big, " = ", res_oflow

!      IEEE divide-by-zero condition (Divide by Zero Raised)

       res_dbyz = -big / zero

       write(6,100)"Div-by-zero: ", -big, " /", zero, " = ", res_dbyz

!      IEEE invalid condition (Invalid Raised)

       res_inv = zero / zero

       write(6,100)"Invalid: ", zero, " /", zero, " = ", res_inv

 100   format(A14,E8.1,A2,E8.1,A2,E10.1)

       end

Consider the following command line:

ifort fpe.f -fpe0 -g

The following output is produced:

./a.out

   Underflow:  0.1E-29 * 0.1E-09 =   0.0E+00

forrtl: error (72): floating overflow

Image       PC        Routine     Line        Source

a.out       0804A063  Unknown     Unknown  Unknown

a.out       08049E78  Unknown     Unknown  Unknown

Unknown     B746B748  Unknown     Unknown  Unknown

a.out       08049D31  Unknown     Unknown  Unknown

Aborted

The following command line uses -fpe1:

ifort fpe.f -fpe1 -g

The following output is produced:

./a.out

   Underflow:  0.1E-29 * 0.1E-09 =   0.0E+00

    Overflow:  0.1E+31 * 0.1E+31 = Infinity

 Div-by-zero: -0.1E+31 / 0.0E+00 = -Infinity

     Invalid:  0.0E+00 / 0.0E+00 = NaN

The following command line uses -fpe3:

ifort fpe.f -fpe3 -g

The following output is produced:

./a.out

   Underflow:  0.1E-29 * 0.1E-09 =   0.1E-39

    Overflow:  0.1E+31 * 0.1E+31 = Infinity

 Div-by-zero: -0.1E+31 / 0.0E+00 = -Infinity

     Invalid:  0.0E+00 / 0.0E+00 = NaN

Relationship between the -fpe Option and the -ftz Option

The -ftz option affects the results of floating underflow in the following ways:

On IA-32 and Intel® EM64T systems, explicitly setting -ftz can degrade performance since the generated code stream must be synchronized after each floating-point instruction to allow for abrupt underflow fix-up.  Abrupt underflow in SSE is handled by setting the FTZ bit in the MXCSR register; with SSE and SSE2 code, there is no performance degradation and possibly even a performance gain due to the fact that the hardware handles the denormals. The default setting of abrupt underflow affects the SSE hardware, not the instruction stream.

On Itanium®-based processors, gradual underflow to 0 can degrade performance. You can improve performance by using higher optimization levels to get the default abrupt underflow or explicitly setting -ftz.

See Also:

-fpe compiler option
-ftz
compiler option