【问题标题】:Floating point arithmetic rounding to nearest浮点算术四舍五入到最接近
【发布时间】:2013-02-04 11:18:27
【问题描述】:

我对浮点运算中的四舍五入有点困惑。令 a、b 和 c 为归一化的双精度浮点数。 a+b=b+a 是否正确,其中 + 正确舍入到最接近的浮点加法?我最初的猜测是肯定的,这总是正确的,但我不完全理解四舍五入到最近。有人可以举一个例子,当 a+b != b+a 使用浮点加法并四舍五入到最近?

【问题讨论】:

    标签: math floating-point


    【解决方案1】:

    无论舍入模式如何,正确实现的 IEEE-754 浮点加法都是可交换的(a+b 等于 b+a)。

    舍入模式会影响精确的数学结果如何舍入以适应目标格式。由于 a+b 和 b+a 的精确数学结果相同,因此它们的舍入相同。

    【讨论】:

    • 我明白了。它也是关联的吗?例如,(a+b)+c = a+(b+c) 吗?
    • @SKLAK:不。简单的反例:a = 1e16, b = -1e16, c = 1
    • 算术不是关联的,因为更改运算顺序会更改发生舍入错误的位置。例如,计算出的 (a+b)+ca+(b+c) 在数学上是 f(f(a+b)+c)f(a+f(b+c)),其中 f 是将精确的数学值四舍五入为浮点数表示的值的函数。一般来说,f(a+b) 没有理由与f(b+c) 有相同的舍入误差,因此这些可能会产生不同的结果。
    【解决方案2】:

    如上所述,加法是可交换的,但不是结合的。通过运行以下 (MS Visual Studio) C++ 代码可以看出舍入模式的差异:

    #include <iostream>
    #include <float.h>
    
    #pragma fenv_access(on)
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        float a = 1.75f, b = 1e-6f;
    
        cout.setf(ios::fixed,ios::floatfield);
        cout.precision(7);
    
        cout << "a = " << a << ", b = " << b << endl;
    
        _controlfp_s(NULL, _RC_DOWN,_MCW_RC);
    
        cout << "Result of a + b rounded down: " << a+b << endl;
        cout << "Result of a - b rounded down: " << a-b << endl;
    
        _controlfp_s(NULL, _RC_UP,_MCW_RC);
        cout << "Result of a + b rounded up: " << a+b << endl;
        cout << "Result of a - b rounded up: " << a-b << endl;
    
        _controlfp_s(NULL, _RC_NEAR,_MCW_RC);
        cout << "Result of a + b rounded to nearest: " << a+b << endl;
        cout << "Result of a - b rounded to nearest: " << a-b << endl;
    
        return 0;
    }
    

    输出:

    a = 1.7500000, b = 0.0000010
    Result of a + b rounded down: 1.7500010
    Result of a - b rounded down: 1.7499989
    Result of a + b rounded up: 1.7500011
    Result of a - b rounded up: 1.7499990
    Result of a + b rounded to nearest: 1.7500010
    Result of a - b rounded to nearest: 1.7499990
    

    【讨论】:

      猜你喜欢
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多