我正在阅读英特尔手册(英特尔®64和IA-32体系结构软件开发人员手册* 2016),并且很好奇我是否正确理解了有关下溢异常需求的摘录:
-第4.9.1.5节
所以我的问题是这种情况是什么样的?一种可能的伪代码计算是
veryVerySmallNumber = SmallestFloatpossible -1
veryVeryLargeNumber = BigBigFloat
answer = veryVerySmallNumber / veryVeryLargeNumber
我读到处理器可以通过两种方式处理此问题,但我更关心下溢可能导致溢出的方式。我还要感谢您对处理这些情况的一般精神作出的任何澄清。
最佳答案
英特尔对下溢的引用是关于浮点运算的。
该程序:
#include <stdio.h>
int main(void)
{
float x = 0x1.23456p-70f; // Set x to a number around 2**-70.
float y = x*x;
float z = 1/y;
printf("x = %g.\n", x);
printf("y = %g.\n", y);
printf("z = %g.\n", z);
}
在使用IEEE-754 binary32进行
float
打印的常见C实现中:x = 9.63735e-22。
y = 9.29061e-43。
z = inf。
在
x*x
中,计算会下溢-结果在次标准范围内,其中float
格式不能完全精确地表示它(尤其是在将结果四舍五入以适应格式时,结果的某些值会丢失)。然后,由于数字太小,尝试取其倒数不能产生有限的结果-结果超出了有限数的
float
范围,因此会产生无穷大。据说该操作溢出。英特尔硬件提供了一种检测下溢的方法:在未屏蔽FP异常的情况下,下溢异常实际上将被捕获(例如,在Linux/Unix上,操作系统将提供SIGFPE浮点异常)。或像平常一样屏蔽FP异常,它将在MXCSR中设置一个粘性标志位,以记录自上次异常状态标志清零以来发生了下溢异常。还有其他异常标志,用于溢出,不精确(非零舍入错误),无效(NaN结果)。请参阅the MXCSR bits表,或参阅Intel x86手册。对于旧版x87,有类似的单独的屏蔽异常记录标志。
程序可以通过检测
x*x
中的下溢并执行其想要避免在以后的操作中完全失去对值的跟踪的任何步骤来利用此优势。