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%