是否有可能在C ++中下溢浮点加法?

时间:2015-06-18 09:56:43

标签: c++ floating-point

我正在查看英特尔处理器手册,第2A卷,第3.266-3.268页,它指出FADD操作可能会产生#U(下溢)异常。 原因是结果将很小,以便在DST中正确表示。

我想知道是否可以使用本机数据类型(float,double,long double)在C ++上添加下溢,或者如果数据类型的语言包装使得添加操作在下溢方面是安全的。

2 个答案:

答案 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 类型。

英特尔当然指的是逐渐下行。但是考虑到突然下溢,那么仅使用加法和/或减法就无法实现。