当尝试执行的原子算术运算没有生成可普遍接受的结果时,就产生了运算异常。原子和可接受的含义随时间和使用场合而异。(请参见 W. Kahan 编著的《Handling Arithmetic Exceptions》。)
例如,当某个程序尝试求负数的平方根时,会产生异常。这是无效运算异常的一个示例。在出现此类异常时,系统会以下列两种方式之一进行响应:
如果该异常的陷阱处于禁用状态(缺省情况),系统将记录异常发生这一事实,并使用 IEEE 754 针对异常运算指定的缺省结果继续执行该程序。
如果该异常的陷阱处于启用状态,系统将生成 SIGFPE 信号。如果程序安装了 SIGFPE 信号处理程序,系统会将控制转交给该处理程序;否则,该程序将中止。
IEEE 754 定义了五个基本类型的浮点异常:无效运算、除以零、溢出、下溢和不精确。前三个(无效、除和溢出)有时统称为常见异常。这些异常一旦出现,很少可被忽略。ieee_handler(3m) 手册页介绍了一种仅适用于在出现常见异常时自陷的简便方法。 另外两种异常(下溢和不精确)更常见。实际上,大多数浮点运算都会导致不精确异常。这些异常通常(尽管不总是)可以安全地忽略。缺省情况下,Oracle Developer Studio 12.5 C、C++ 和 f77 编译器将禁用所有 IEEE 陷阱。f95 编译器在缺省情况下将对常见异常启用陷阱。可通过使用 f95 –ftrap=none 进行编译来恢复符合 754 标准。
表 31简要介绍了 IEEE 标准 754 中的信息。它描述了五个浮点异常,以及在出现这些异常时 IEEE 运算环境的缺省响应。
|
无序比较:对于任何浮点值对来说,即使它们的格式不同,也可以对它们进行比较。可能有四种互斥关系:小于、大于、等于或无序。无序意味着至少有一个操作数为 NaN(not a number,非数)。
每个 NaN 可与任何值(包括它本身)进行“无序”比较。 下表显示在关系为无序时,由哪一种谓词导致无效运算异常。
|
无效转换:尝试将 NaN 或无穷大转换为整数,或者在从浮点格式转换时出现整数溢出。
IEEE 单精度、双精度和扩展格式能表示的最小正规数分别为 2-126、2-1022 和 2-16382。有关 IEEE 浮点格式的说明,请参见IEEE 运算。
下表列出了针对溢出禁用陷阱时的缺省结果。以下结果取决于舍入模式和中间结果的符号。
|
x86 浮点环境提供另一个未在 IEEE 标准中提到的异常:非正规操作数异常。当针对次正规数执行浮点运算时,会出现该异常。
异常的优先顺序如下所示:无效(优先级最高)、溢出、除、下溢、不精确(优先级最低)。 在基于 x86 的系统上,非正规操作数异常在所有异常中的优先级最低。
能够在单个运算中同时发生的标准异常只有不精确的溢出和不精确的下溢这两种组合。在基于 x86 的系统上,非正规操作数异常可以与五个标准异常中的任意一个同时发生。如果启用了对溢出、下溢和不精确的捕获,则溢出和下溢陷阱的优先级高于不精确陷阱;在基于 x86 的系统上,溢出、下溢和不精确陷阱的优先级都高于非正规操作数陷阱。