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

退出打印视图

更新时间: 2015 年 1 月
 
 

4.2 什么是异常?

很难对异常进行定义。 下面引用 W.Kahan 的话:

当尝试执行的原子算术运算没有生成可普遍接受的结果时,就产生了运算异常。原子和可接受的含义随时间和使用场合而异。(请参见 W. Kahan 编著的《Handling Arithmetic Exceptions》。)

例如,当某个程序尝试求负数的平方根时,会产生异常。这是无效运算异常的一个示例。在出现此类异常时,系统会以下列两种方式之一进行响应:

  • 如果该异常的陷阱处于禁用状态(缺省情况),系统将记录异常发生这一事实,并使用 IEEE 754 针对异常运算指定的缺省结果继续执行该程序。

  • 如果该异常的陷阱处于启用状态,系统将生成 SIGFPE 信号。如果程序安装了 SIGFPE 信号处理程序,系统会将控制转交给该处理程序;否则,该程序将中止。

IEEE 754 定义了五个基本类型的浮点异常:无效运算、除以零、溢出、下溢不精确。前三个(无效、除和溢出)有时统称为常见异常。这些异常一旦出现,很少可被忽略。ieee_handler(3m) 手册页介绍了一种仅适用于在出现常见异常时自陷的简便方法。 另外两种异常(下溢和不精确)更常见。实际上,大多数浮点运算都会导致不精确异常。这些异常通常(尽管不总是)可以安全地忽略。缺省情况下,Oracle Solaris Studio 12.4 C、C++ 和 f77 编译器将禁用所有 IEEE 陷阱。f95 编译器在缺省情况下将对常见异常启用陷阱。可通过使用 f95 –ftrap=none 进行编译来恢复符合 754 标准。

Table 4–1 简要介绍了 IEEE 标准 754 中的信息。它描述了五个浮点异常,以及在出现这些异常时 IEEE 运算环境的缺省响应。

表 4-1  IEEE 浮点异常
IEEE
异常
出现异常的原因
示例
在陷阱被禁用时
出现的缺省结果
无效运算
对于将要执行的运算,某个操作数无效。
(在 x86 上,当浮点栈下溢或溢出时也会出现该异常,尽管这不符合 IEEE 标准。)
  • 0 × ∞

  • 0 / 0

  • ∞ / ∞

  • x REM 0

  • 负数平方根的操作数

  • 信号 NaN 操作数的任何运算

  • 无序比较(请参见注释 1)

  • 无效转换(请参见注释 2)

无噪声 NaN
除以零
针对有限操作数执行运算时生成精确的无穷大结果。
  • 对于有限的非零 x,x / 0

  • log(0)

带有正确符号的无穷大
溢出
正确舍入的结果将比可用目标格式表示的最大有限数大的多(即,超过指数范围)。
  • 双精度:

    • DBL_MAX + 1.0e294

    • exp(709.8)

  • 单精度:

    • (浮点)DBL_MAX

    • FLT_MAX + 1.0e32

    • expf(88.8)

取决于舍入模式 (RM),以及中间结果的符号。请参见表 4-1 的注释中的第 4 项。
下溢
精确结果或正确舍入的结果将比可用目标格式表示的最小正常数小的多(请参见注释 3)。
  • 双精度:

    • nextafter(min_normal,-·)

    • nextafter(min_subnormal,-·)

    • DBL_MIN §3.0

    • exp(-708.5)

  • 单精度:

    • (浮点)DBL_MIN

    • nextafterf(FLT_MIN, -·)

    • expf(-87.4)

低于正常值或零
不精确
有效运算的舍入结果不同于无限精确结果。(大多数浮点运算都产生该异常。)
  • 2.0 / 3.0

  • (浮点)1.12345678

  • log(1.1)

  • DBL_MAX + DBL_MAX,当没有溢出陷阱时

该运算的结果(舍入、溢出或下溢)