繁体   English   中英

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

[英]Interchangeability of IEEE 754 floating-point addition and multiplication

加法x + x可以通过IEEE 754(IEC 559)浮点标准中的乘法2 * x x + 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);
}

加法x + x可通过IEEE 754(IEC 559)浮点标准中的乘法2 * x x + x互换

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

或者更一般地说,是否有任何保证case_add和case_mul始终给出完全相同的结果?

不一般,没有。 据我所知,它似乎适用于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它失败,例如,取x1.00000000000000021.0之后的下一个double 6.000000000000002 ),在这种情况下, 6x6.000000000000002x+x+x+x+x+x6.000000000000001

如果n是例如pow(2, 54)则乘法将正常工作,但是在加法路径中,一旦结果值足够大于输入xresult += x将产生result

是的,但它并不普遍。 乘以高于2的数字可能不会给出相同的结果,因为您更改了指数,如果替换为adds,则可能会略微下降。 但是,如果由添加操作替换,乘以2则不会丢失一点。

如果case_add的累加器result变得太大,则添加x将引入舍入误差。 在某个时刻,添加x根本不会产生任何影响。 所以函数不会给出相同的结果。

例如,如果double x = 0x1.0000000000001p0 (十六进制浮点表示法):

n  case_add              case_mul

1  0x1.0000000000001p+0  0x1.0000000000001p+0
2  0x1.0000000000001p+1  0x1.0000000000001p+1
3  0x1.8000000000002p+1  0x1.8000000000002p+1
4  0x1.0000000000001p+2  0x1.0000000000001p+2
5  0x1.4000000000001p+2  0x1.4000000000001p+2
6  0x1.8000000000001p+2  0x1.8000000000002p+2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM