是否可以在C++中下溢浮点添加

Is it possible to underflow a floating point addition in C++?

本文关键字:下溢 添加 C++ 是否      更新时间:2023-10-16

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

我想知道是否可以在使用本机数据类型(浮点型、双精度型、长双精度型)的C++上加法下溢,或者数据类型的语言包装是否使加法操作在下溢方面是安全的。

如果添加彼此非常接近的正数和负数,产生非正常值,则设置下溢标志(如果未屏蔽下溢异常)。链接到英特尔文章异常和下溢。

示例代码(使用Microsoft编译器):

    double a,b,c;
    a =  2.2250738585072019e-308;
    b = -2.2250738585072014e-308;
    c = a + b;   /* c is denormal */
    printf("%28.16le %016llxn", a, a);
    printf("%28.16le %016llxn", b, b);
    printf("%28.16le %016llxn", 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
    }

当计算结果为非正态(次正规)数字时,会发生下溢情况。这正式称为渐进下溢(而不是产生零)。因此,通过添加几乎任何两个非正常数,只要结果也是异常数,就会发生下溢。例如:

pow(2.0, -1074.0) + pow(2.0, -1073.0)

此处的所有操作数均为双精度类型。

英特尔当然指的是逐渐下溢。但是,考虑到突然的下溢,仅使用加法和/或减法是不可能的。