IEEE 浮点数何时保证 (x==(x+y)-y) 或 (x==(x-y)+y)?

When is (x==(x+y)-y) or (x==(x-y)+y) guaranteed for IEEE floats?

在 C 或其他使用 IEEE 浮点数的语言中,我有两个变量 xy,它们都保证是有限的,非 NaN,基本上是正常的数字。

我有一些代码假定以下代码在本质上没有任何效果:

float x = get_x ();
float y = get_y ();

float old_x = x;
x += y;
x -= y;
assert (old_x == x);
x -= y;
x += y;
assert (old_x == x);

我知道这对于某些 类 值是正确的,即那些尾数中没有 "many" 有效数字的值,但我想弄清楚边缘情况.

例如,二进制表达式 1.3 的尾数一直是有效数字,1.7 也是如此,我不应该假设 1.3+1.7==3 正好,但是我可以假设如果我将这些数字加在一起然后减去它们,反之亦然,我会再次得到第一个值吗?

这个的正式边缘条件是什么?

浮点管道中的位数不是标准的一部分。

来自维基百科:

The standard also recommends extended format(s) to be used to perform internal computations at a higher precision than that required for the final result, to minimise round-off errors: the standard only specifies minimum precision and exponent requirements for such formats. The x87 80-bit extended format is the most commonly implemented extended format that meets these requirements.

因此,由于内部格式可以扩展,不知道内部格式何时被截断为标准格式,使用的是什么舍入方法,假设添加一个值然后再次减去它会得到原始值是标准不保证。

对于您发布的微不足道的案例,它可能在大多数情况下都有效。

然后就是处理NAN的情况

您也许能够确定您当前使用的架构的边缘情况,但检查当前值是否在原始值的误差范围内可能更容易。