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 浮点数的语言中,我有两个变量 x
和 y
,它们都保证是有限的,非 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的情况
您也许能够确定您当前使用的架构的边缘情况,但检查当前值是否在原始值的误差范围内可能更容易。
在 C 或其他使用 IEEE 浮点数的语言中,我有两个变量 x
和 y
,它们都保证是有限的,非 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的情况
您也许能够确定您当前使用的架构的边缘情况,但检查当前值是否在原始值的误差范围内可能更容易。