Sun Studio 12:Fortran 编程指南

6.3.1 标志和 ieee_flags()

ieee_flags 函数用于查询和清除异常状态标志。它是 Sun 编译器随带的 libsunmath 库的一部分,可执行下列任务:

ieee_flags 调用的一般形式为:


      
flags = ieee_flags( action, mode, in, out )

四个参数中的每一个都是字符串。输入为 actionmodein。输出为 outflagsieee_flags 是一个整数值函数。flags 中返回有用的信息,作为 1 位标志集合。有关完整信息,请参见 ieee_flags(3m) 手册页。

下表显示了所有可能的参数值。

表 6–1 ieee_flags ( action, mode, in, out ) 参数值

参数 

允许值 

action

get, set, clear, clearall

mode

direction, exception

in, out

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

注意,这些是文字字符串,且输出参数 out 必须至少是 CHARACTER*9inout 的可能值的含义取决于与其一起使用的 action 和 mode。下表对此进行了概括:

表 6–2 ieee_flags in、 out 参数的含义

inout 的值

所指 

nearest, tozero, negative, positive

舍入方向 

extended, double, single

舍入精度 

inexact, division, underflow, overflow, invalid

异常 

all

全部五种异常 

common

常见异常:无效、除法、上溢 

例如,要确定引起了标志的具有最高优先级的异常,请将输入参数 in 作为空字符串传递:


      CHARACTER *9, out
      ieeer = ieee_flags( ’get’, ’exception’, ’’, out )
      PRINT *, out, ’ flag raised’

另外,要确定是否引起了 overflow 异常标志,请将输入参数 in 设置为 overflow。返回时,如果 out 等于 overflow,会出现 overflow 异常标志;否则不会出现该标志。


      ieeer = ieee_flags( ’get’, ’exception’, ’overflow’, out )
      IF ( out.eq. ’overflow’) PRINT *,’overflow flag raised’

示例:清除 invalid 异常:


      ieeer = ieee_flags( ’clear’, ’exception’, ’invalid’, out )

示例:清除所有异常:


      ieeer = ieee_flags( ’clear’, ’exception’, ’all’, out )

示例:将舍入方向设置为零:


      ieeer = ieee_flags( ’set’, ’direction’, ’tozero’, out )

示例:将舍入精度设置为 double


      ieeer = ieee_flags( ’set’, ’precision’, ’double’, out )

6.3.1.1 用 ieee_flags 关闭所有警告消息。

使用清除 action 调用 ieee_flags(如下例所示)可以重置任何未清除的异常。在程序退出之前进行该调用,可禁止系统在程序终止时产生浮点异常警告消息。

示例:用 ieee_flags() 清除所有产生的异常:


      i = ieee_flags(’clear’, ’exception’, ’all’, out )

6.3.1.2 用 ieee_flags 检测异常

以下示例演示如何确定早期计算引起的浮点异常。会将系统 include 文件 floatingpoint.h 中定义的位屏蔽应用于 ieee_flags 的返回值。

在以下示例(即 DetExcFlg.F)中,include 文件是使用 #include 预处理程序指令引入的,这就要求以 .F 后缀命名源文件。下溢是由最小的双精度数除以 2 引起的。

示例:使用 ieee_flags 检测异常,然后对其进行解码:


#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

示例:编译并运行上述示例 (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%