ieee_flags 函数用于查询和清除异常状态标志。它是 Sun 编译器随带的 libsunmath 库的一部分,可执行下列任务:
控制舍入方向和舍入精度
检查异常标志状态
清除异常状态标志
ieee_flags 调用的一般形式为:
flags = ieee_flags( action, mode, in, out ) |
四个参数中的每一个都是字符串。输入为 action、mode 和 in。输出为 out 和 flags。ieee_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*9。in 和 out 的可能值的含义取决于与其一起使用的 action 和 mode。下表对此进行了概括:
表 6–2 ieee_flags in、 out 参数的含义
in 和 out 的值 |
所指 |
---|---|
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 ) |
使用清除 action 调用 ieee_flags(如下例所示)可以重置任何未清除的异常。在程序退出之前进行该调用,可禁止系统在程序终止时产生浮点异常警告消息。
示例:用 ieee_flags() 清除所有产生的异常:
i = ieee_flags(’clear’, ’exception’, ’all’, out ) |
以下示例演示如何确定早期计算引起的浮点异常。会将系统 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% |