c++ - IEEE 754 浮点加法和乘法的互换性

标签 c++ floating-point ieee-754 numerical-stability

IEEE 754 (IEC 559) 浮点标准中,加法 x + x 是否可以与乘法 2 * x 互换,或者更一般地说,是否可以保证 case_addcase_mul 总是 给出完全相同的结果?

#include <limits>

template <typename T>
T case_add(T x, size_t n)
{
    static_assert(std::numeric_limits<T>::is_iec559, "invalid type");

    T result(x);

    for (size_t i = 1; i < n; ++i)
    {
        result += x;
    }

    return result;
}

template <typename T>
T case_mul(T x, size_t n)
{
    static_assert(std::numeric_limits<T>::is_iec559, "invalid type");

    return x * static_cast<T>(n);
}

最佳答案

Is the addition x + x interchangeable by the multiplication 2 * x in IEEE 754 (IEC 559) floating-point standard

是的,因为它们在数学上是相同的,所以它们会给出相同的结果(因为结果是精确的 float )。

or more generally speaking is there any guarantee that case_add and case_mul always give exactly the same result?

一般不会,不会。据我所知,它似乎适用于 n <= 5。 :

  • n=3 : 作为 x+x是精确的(即不涉及四舍五入),所以 (x+x)+x只涉及最后一步的一轮舍入。
  • n=4 (并且您使用的是默认舍入模式)然后

    • 如果 x 的最后一位为 0,则 x+x+x是精确的,因此结果与 n=3 的参数相同.
    • 如果最后两位是01 , 然后是 x+x+x 的精确值将具有 1|1 的最后 2 位(其中 | 表示格式中的最后一位),这将向上取整为 0|0 .下一次添加将给出准确的结果 |01 ,因此结果将向下舍入,抵消之前的错误。
    • 如果最后两位是11 , 然后是 x+x+x 的精确值将具有 0|1 的最后 2 位, 将向下舍入为 0|0 .下一次添加将给出准确的结果 |11 , 因此结果将向上舍入,再次抵消之前的错误。
  • n=5 (同样,假设默认舍入):因为 x+x+x+x是准确的,其成立的原因与 n=3 相同.

对于 n=6它失败了,例如拿x成为1.0000000000000002 (下一个 double1.0 之后),在这种情况下 6x6.000000000000002x+x+x+x+x+x6.000000000000001

关于c++ - IEEE 754 浮点加法和乘法的互换性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39855825/

相关文章:

c++ - 制作适用于 C++ 代码的 GUI

javascript - Javascript中 float 的最大精度(小数点后)是多少

bash - 如何根据语言环境变量格式化 float 以供显示?

r - 在 R 中实现 nextafter 功能

javascript - 在 asm.js 代码中检查 NaN

c++ - 是否可以从类创建多维数组?

c++ - 压缩 switch 语句?

python - Python为什么要四舍五入?

c++ - 什么是 undefined reference /未解析的外部符号错误以及如何修复它?

floating-point - - (- x) = x 在浮点运算中是否正确?