Sun Studio 12: Fortran Programming Guide

6.3.1 Flags and ieee_flags()

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:

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

Argument  

Values Allowed  

action

get, set, clear, clearall

mode

direction, exception

in, out

nearest, tozero, negative, positive, extended, double single, inexact, division, underflow, overflow, invalid all, common

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 in, out 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 )

6.3.1.1 Turning Off All Warning Messages With ieee_flags

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 )

6.3.1.2 Detecting an Exception With ieee_flags

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 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 "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% f95 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%