IEEE 运算是一种处理会导致如下问题的运算操作的相对较新的方法:无效操作数、被零除、上溢、下 溢或结果不精确。不同之处在于舍入、近零数字的处理以及接近机器最大值的数字的处理。
IEEE 标准支持用户处理异常、舍入和精度。因此,此标准支持区间运算和异常诊断。IEEE 标准 754 可以使诸如 exp 和 cos 之类的基本函数标准化,以便创建高精确度的运算,并结合数值和符号代数计算。
与其他任何种类的浮点运算相比,IEEE 运算向用户提供了对计算的更强大控制。此标准简化了编写复杂可移植数值程序的任务。很多有关浮点算法的问题都涉及数的基本运算。例如:
当计算机硬件无法表示无限精确的结果时,运算结果会怎样?
有些基本运算(比如乘法和加法)是否具有交换性?
另一类问题与浮点异常及异常处理有关。如果进行下列运算会发生什么情况:
二个非常大的同号数字相乘?
非零值除以零?
零除以零?
在较早的运算模型中,第一类问题可能不会得到预期的答案,而第二类问题中的异常情况可能都会得到相同的结果:程序立即中止或使用无用结果继续执行。
此标准可确保运算产生具有预期性质的、符合数学预期的结果。它还确保异常情况产生指定的结果,除非用户明确地指定其他选项。
例如,直观地引入了异常值 +Inf、-Inf 和 NaN:
big*big = +Inf 正无穷
big*(-big) = -Inf 负无穷
num/0.0 = +Inf 其中 num > 0.0
num/0.0 = -Inf 其中 num < 0.0
0.0/0.0 = NaN 非数字
无效。运算操作数在数学上无效-例如,0.0/0.0、sqrt(-1.0) 和 log(-37.8)
被零除。除数为零,被除数为有限的非零数字-例如,9.9/0.0
上溢。运算产生的结果超出指数范围-例如,MAXDOUBLE+0.0000000000001e308
下溢。运算产生的结果太小,无法用正常数字表示-例如,MINDOUBLE * MINDOUBLE
在《数值计算指南》中介绍了 IEEE 标准的实现。
-ftrap=mode 选项可捕获浮点异常。如果 ieee_handler() 调用未建立信号处理程序,异常会用内存转储核心转储文件终止程序。有关该编译器选项的详细信息,请参见《Fortran 用户指南》。例如,为了能够捕获上溢、被零除和无效运算,可使用 -ftrap=common 进行编译。(这是 f95 的缺省选项。)
必须使用 -ftrap= 编译应用程序的主程序才能进行捕获。
f95 程序不会自动报告异常。要显示程序终止时产生的浮点异常列表,需要显式调用 ieee_retrospective(3M)。一般情况下,如果发生了无效、被零除或上溢异常中的任何一种,都会产生消息。不精确异常不会产生消息,因为它们在实际程序中发生得过于频繁。
ieee_retrospective函数对浮点状态寄存器进行查询,以找出产生了哪些异常,并打印一条有关标准错误的消息来通知您哪些是已产生但尚未清除的异常。此消息通常如下所示;格式可能会随各编译器版本而变化:
Note: IEEE floating-point exception flags raised: Division by Zero; IEEE floating-point exception traps enabled: inexact; underflow; overflow; invalid operation; See the Numerical Computation Guide, ieee_flags(3M), ieee_handler(3M) |
Fortran 95 程序需要显式调用 ieee_retrospective,并使用 -xlang=f77 进行编译,以便与 f77 兼容库进行链接。
用 -f77 兼容标志进行编译,将启用程序终止时自动调用 ieee_retrospective 惯例。
可以使用 ieee_flags() 关闭任意或所有这些消息,方法是在调用 ieee_retrospective 之前清除异常状态标记。
根据 IEEE 标准进行异常处理是 SPARC 和 x86 处理器上的缺省异常处理方法。但是,检测浮点异常和生成浮点异常信号(SIGFPE)之间是有区别的。
按照 IEEE 标准,当浮点运算期间出现未捕获的异常时,会发生两件事情:
系统返回缺省结果。例如,对于 0/0 (invalid),系统返回结果为 NaN。
会设置标志来指示引起了异常。例如,对于 0/0 (invalid),系统会设置“无效运算”标志。
f95 在处理浮点异常方面与早期的 f77 编译器有着明显的区别。
缺省情况下,f95 会自动捕获被零除、上溢和无效运算。而 f77 在缺省情况下不会为浮点异常自动产生信号来中断正在运行的程序。其假设是:只要返回期望的值,大多数异常都无关紧要,对其进行捕获会降低性能。
可以使用 f95 命令行选项 -ftrap 来更改缺省设置。f95 的缺省选项是 -ftrap=common。要按早期的 f77 缺省设置进行运算,请使用 -ftrap=%none 编译主程序。
可以手动禁用标准 IEEE 运算中一个称为渐进下溢的特征。禁用后,程序将被视为在非标准运算下运行。
IEEE 运算标准规定了一种通过动态调整有效数的小数点来渐进处理下溢结果的方法。按 IEEE 浮点格式,小数点出现在有效数之前,并且有一个隐式前导位 1。当浮点计算结果会下溢时,渐进下溢允许将此隐式前导位清为 0,并将小数点移入有效数之中,否则,浮点计算结果便会产生下溢。对于 SPARC 处理器,该结果不是在硬件而是在软件中完成的。如果程序产生的下溢很多(也许这表示您的算法有问题),可能会导致性能损失。
可以通过以下方式禁用然后关闭渐进下溢: 使用 -fns 选项进行编译,或从程序内调用库例程 nonstandard_arithmetic()。调用 standard_arithmetic() 可重新开启渐进下溢。
为提高效率,必须用 -fns 编译应用程序的主程序。参见《Fortran 用户指南》。
对于传统应用程序,请注意: