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

The -fpe*n* option allows some control over the results of floating-point exceptions.

**-fpe0** restricts floating-point exceptions as follows:

- Enables the overflow, the divide-by-zero, and the invalid floating-point exceptions. The program will print an error message and abort if any of these exceptions occurs. If a floating-point underflow occurs, the result is set to zero and execution continues. This is called flush-to-zero. This option sets -IPF_fp_speculationstrict if no specific -IPF_fp_speculation option is specified. The -fpe0 option sets -ftz. To get more detailed location information about where the exception occurred, use -traceback.

**-fpe1** restricts only floating-point underflow:

- Floating-point overflow, floating-point divide-by-zero, and floating-point invalid produce exceptional values (NaN and signed Infinities) and execution continues. If a floating-point underflow occurs, the result is set to zero and execution continues. The -fpe1 option sets -ftz.

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

- Floating overflow, floating divide-by-zero, and floating invalid produce exceptional values (NaN and signed Infinities) and execution continues. 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 -fpe*n*.

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

## Leave a Reply