Oracle® Solaris Studio 12.4:数值计算指南

退出打印视图

更新时间: 2015 年 1 月
 
 

4.3.1 ieee_flags(3m)

ieee_flags 为类似于 Oracle Solaris Studio C、C++ 和 Fortran 的 IEE 754 异常标志提供了一个接口。然而,只能在 Oracle Solaris OS 上使用此接口。对移植范围更广的 C 和 C++ 程序使用 C99 异常标志函数

调用 ieee_flags(3m) 的语法为:

i = ieee_flags(action, mode, in, out);

程序可提供字符串 "exception" 并将其作为第二个参数,从而可使用 ieee_flags 函数测试、设置或清除已发生异常状态标志。例如,要从 Fortran 中清除溢出异常标志,请编写:

      character*8 out
      call ieee_flags('clear', 'exception', 'overflow', out) 

要确定是否在 C 或 C++ 中发生了异常,请使用:

      i = ieee_flags("get", "exception", in, out); 

当操作为 "get" 时,out 中返回的字符串为以下之一:

  • "not available"-如果异常信息不可用

  • ""(空字符串)-如果没有已发生异常,或者对于 x86,非正规操作数是唯一的已发生异常

  • 在第三个参数 in 中命名的异常的名称,如果出现了该异常

  • 否则,返回已出现的、优先级最高的异常的名称

例如,在以下 Fortran 调用中,如果出现了除以零异常,则 out 中返回的字符串为 "division"。否则返回已出现的、优先级最高的异常的名称:

      character*8 out
      i = ieee_flags('get', 'exception', 'division', out)

请注意,除非 in 指定具体的异常,否则它将被忽略。例如,在 C 调用中,将忽略参数 "all"

      i = ieee_flags("get", "exception", "all", out); 

除了在 out 中返回异常的名称以外,ieee_flags 还返回一个结合当前引发的所有异常的整数值。此值是所有已发生异常标志的按位“或”,其中的每个标志都用一位表示,如Table 4–2 中所示。与每个异常相对应的位的位置由 fp_exception_type 值(定义在 sys/ieeefp.h 文件中)给出。(请注意,这些位的位置与计算机有关且不必连续。)

表 4-2  异常位
异常
位的位置
已发生异常位
invalid
fp_invalid
i & (1 << fp_invalid)
overflow
fp_overflow
i & (1 << fp_overflow)
division
fp_division
i & (1 << fp_division)
underflow
fp_underflow
i & (1 << fp_underflow)
inexact
fp_inexact
i & (1 << fp_inexact)
denormalized
fp_denormalized
i & (1 << fp_denormalized) (仅限 x86)

下面的 C 或 C++ 程序段显示一种用来对返回值进行解码的方法。

/*
 *   Decode integer that describes all accrued exceptions. 
 *   fp_inexact etc. are defined in <sys/ieeefp.h> 
 */ 
 
char *out; 
int invalid, division, overflow, underflow, inexact; 
 
code = ieee_flags("get", "exception", "", &out); 
printf ("out is %s, code is %d, in hex: 0x%08X\n", 
  out, code, code); 
inexact  =  (code >> fp_inexact) & 0x1; 
division  =  (code >> fp_division) & 0x1; 
underflow  =  (code >> fp_underflow) & 0x1; 
overflow  =  (code >> fp_overflow) & 0x1; 
invalid  =  (code >> fp_invalid) & 0x1; 
printf("%d %d %d %d %d \n", invalid, division, overflow,
  underflow, inexact);