我正在查看英特尔处理器手册,第2A卷,第3.266-3.268页,它指出FADD操作可能会产生#U(下溢)异常。 原因是结果将很小,以便在DST中正确表示。
我想知道是否可以使用本机数据类型(float,double,long double)在C ++上添加下溢,或者如果数据类型的语言包装使得添加操作在下溢方面是安全的。
答案 0 :(得分:2)
如果添加彼此非常接近的正数和负数,产生denormal,则设置下溢标志(如果未屏蔽下溢异常)。链接到英特尔文章denormals and underflow。
示例代码(使用Microsoft编译器):
double a,b,c;
a = 2.2250738585072019e-308;
b = -2.2250738585072014e-308;
c = a + b; /* c is denormal */
printf("%28.16le %016llx\n", a, a);
printf("%28.16le %016llx\n", b, b);
printf("%28.16le %016llx\n", c, c);
if ( std::fpclassify( c ) == FP_SUBNORMAL ) printf("c is DENORMAL");
启用(取消屏蔽)下溢异常(Microsoft编译器):
short fcw; /* floating point control word - 16 bit */
/* enable underflow exception */
__asm{
fnstcw fcw
and fcw,0ffefh
fldcw fcw
}
答案 1 :(得分:2)
当计算结果是非正规(次正规)数时,发生下溢情况。这正式称为渐进下溢(与产生零相反)。因此,通过添加几乎任何两个非正规数,只要结果也是非正规数,就会发生下溢。例如:
pow(2.0, -1074.0) + pow(2.0, -1073.0)
此处的所有操作数均为 double 类型。
英特尔当然指的是逐渐下行。但是考虑到突然下溢,那么仅使用加法和/或减法就无法实现。