The ieee_flags function is used to query and clear exception status flags. It is part of the libsunmath library shipped with Sun compilers and performs the following tasks:
Controls rounding direction and rounding precision
Checks the status of the exception flags
Clears exception status flags
The general form of a call to ieee_flags is:
flags = ieee_flags( action, mode, in, out )
Each of the four arguments is a string. The input is action, mode, and in. The output is out and flags. ieee_flags is an integer-valued function. Useful information is returned in flags as a set of 1-bit flags. Refer to the man page for ieee_flags(3m) for complete details.
Possible parameter values are shown in the following table:
Table 6-1 ieee_flags( action, mode, in, out ) Argument Values|
action |
mode |
in, out |
|---|---|---|
|
get set clear clearall |
direction precision exception |
nearest tozero negative positive extended double single inexact division underflow overflow invalid all common |
The precision mode is available only on x86 platforms.
Note that these are literal character strings, and the output parameter out must be at least CHARACTER*9. The meanings of the possible values for in and out depend on the action and mode they are used with. These are summarized in the following table:
Table 6-2 ieee_flags Argument Meanings|
Value of in and out |
Refers to |
|---|---|
|
nearest, tozero, negative, positive |
Rounding direction |
|
extended, double, single |
Rounding precision |
|
inexact, division, underflow, overflow, invalid |
Exceptions |
|
all |
All five exceptions |
|
common |
Common exceptions: invalid, division, overflow |
For example, to determine what is the highest priority exception that has a flag raised, pass the input argument in as the null string:
CHARACTER *9, out
ieeer = ieee_flags( 'get', 'exception', '', out )
PRINT *, out, ' flag raised'
Also, to determine if the overflow exception flag is raised, set the input argument in to overflow. On return, if out equals overflow, then the overflow exception flag is raised; otherwise it is not raised.
ieeer = ieee_flags( 'get', 'exception', 'overflow', out )
IF ( out.eq. 'overflow') PRINT *,'overflow flag raised'
Example: Clear the invalid exception:
ieeer = ieee_flags( 'clear', 'exception', 'invalid', out )
Example: Clear all exceptions:
ieeer = ieee_flags( 'clear', 'exception', 'all', out )
Example: Set rounding direction to zero:
ieeer = ieee_flags( 'set', 'direction', 'tozero', out )
Example: Set rounding precision to double:
ieeer = ieee_flags( 'set', 'precision', 'double', out )
Calling ieee_flags with an action of clear, as shown in the following example, resets any uncleared exceptions. Put this call before the program exits to suppress system warning messages about floating-point exceptions at program termination.
Example: Clear all accrued exceptions with ieee_flags():
i = ieee_flags('clear', 'exception', 'all', out )
The following example demonstrates how to determine which floating-point exceptions have been raised by earlier computations. Bit masks defined in the system include file f77_floatingpoint.h are applied to the value returned by ieee_flags.
In this example, DetExcFlg.F, the include file is introduced using the #include preprocessor directive, which requires us to name the source file with a .F suffix. Underflow is caused by dividing the smallest double-precision number by 2.
Example: Detect an exception using ieee_flags and decode it:
#include "f77_floatingpoint.h"
CHARACTER*16 out
DOUBLE PRECISION d_max_subnormal, x
INTEGER div, flgs, inv, inx, over, under
x = d_max_subnormal() / 2.0 ! Cause underflow
flgs=ieee_flags('get','exception','',out) ! Which are raised?
inx = and(rshift(flgs, fp_inexact) , 1) ! Decode
div = and(rshift(flgs, fp_division) , 1) ! the value
under = and(rshift(flgs, fp_underflow), 1) ! returned
over = and(rshift(flgs, fp_overflow) , 1) ! by
inv = and(rshift(flgs, fp_invalid) , 1) ! ieee_flags
PRINT *, "Highest priority exception is: ", out
PRINT *, ' invalid divide overflo underflo inexact'
PRINT '(5i8)', inv, div, over, under, inx
PRINT *, '(1 = exception is raised; 0 = it is not)'
i = ieee_flags('clear', 'exception', 'all', out) ! Clear all
END
Example: Compile and run the preceding example (DetExcFlg.F):
demo% f77 -silent DetExcFlg.F
demo% a.out
Highest priority exception is: underflow
invalid divide overflo underflo inexact
0 0 0 1 1
(1 = exception is raised; 0 = it is not)
demo%