附加的x + x是否可以与IEEE 754(IEC 559)浮点标准中的乘法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);
}

最佳答案



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



一般而言,不。据我所知,n <= 5似乎成立了:

  • n=3:因为x+x是精确的(即不涉及四舍五入),所以(x+x)+x在最后一步仅涉及一个四舍五入。
  • n=4(并且您使用的是默认的舍入模式),然后
  • 如果x的最后一位为0,则x+x+x是精确的,因此结果与n=3相同,因此结果相同。
  • 如果最后2位是01,则x+x+x的确切值将具有1|1的最后2位(其中|表示格式的最后一位),将四舍五入为0|0。下一个加法将给出精确的结果|01,因此结果将四舍五入,以消除上一个错误。
  • 如果最后2位是11,则x+x+x的确切值将具有0|1的最后2位,将四舍五入为0|0。下一个加法将给出精确的结果|11,因此结果将被四舍五入,再次消除上一个错误。
  • n=5(同样,假设使用默认的四舍五入方法):由于x+x+x+x是精确的,因此其持有的原因与n=3相同。

  • 对于n=6,它会失败,例如将x设为1.0000000000000002(double之后的下一个1.0),在这种情况下,6x6.000000000000002,而x+x+x+x+x+x6.000000000000001

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

    10-11 16:25