C++ ieee754浮点除法的可逆性

C++ ieee754浮点除法的可逆性,c++,floating-point,precision,floating-accuracy,ieee-754,C++,Floating Point,Precision,Floating Accuracy,Ieee 754,IEEE 754浮点除法的可逆性是什么?我的意思是,标准是否保证如果double y=1.0/x,那么x==1.0/y,即x可以精确地逐位恢复 当y为infinity或NaN时的情况是明显的例外。显然不是。1/10没有代表权。你会得到一个近似值。倒过来不会给你10 编辑:有很多这样的。任何需要超过53位的逆运算都将是其中之一 有一个简单的测试。在C语言中,你可以测试1.0/(1.0/10.0)和10.0,你会发现它们不相等。是的,有IEEE 754双精度(*)值x就是这样的x!=1.0/(1.0

IEEE 754浮点除法的可逆性是什么?我的意思是,标准是否保证如果
double y=1.0/x
,那么
x==1.0/y
,即
x
可以精确地逐位恢复


y
infinity
NaN
时的情况是明显的例外。

显然不是。1/10没有代表权。你会得到一个近似值。倒过来不会给你10

编辑:有很多这样的。任何需要超过53位的逆运算都将是其中之一


有一个简单的测试。在C语言中,你可以测试1.0/(1.0/10.0)和10.0,你会发现它们不相等。

是的,有IEEE 754双精度(*)值
x
就是这样的
x!=1.0/(1.0/x)

手动构建具有此属性的正常值的示例很容易:在中写入的
0x1.fffffffffffff p0
是这样的
1.0/(1.0/0x1.fffffffffffff p0)==0x1.fffffffffffffffff ep0
。很自然地,我们期望
0x1.fffffffffffff p0
是一个反例,因为
1.0/0x1.fffffffffffff p0
落在二进制码的开头,在二进制码中,浮点数的密度较低,所以在最里面的部分必须发生较大的相对误差。更准确地说,
1.0/0x1.fffffffffffff p0
正好位于
0.5
与其双精度后继值之间的中点之上,因此
1.0/0x1.fffffffffffff p0
被四舍五入到0.5的后继值,具有较大的相对误差

在十进制
%.16e
格式中,
0x1.ffffffffffffp0
1.99999999998e+00
0x1.ffffffffffffep0
1.99999999999996e+00


(*)对于任何IEEE 754格式,逆函数都没有理由具有问题中的属性

在一些明显的情况下它不能,例如无穷大和不定数,也可能是非规范化数。但对于其他人来说,这是一个好问题。这似乎对零和无穷大都适用……通过简单的反例,我们可以证明符合IEEE-754的浮点倒数不能以这种方式还原。例如,使用四舍五入模式到最近或偶数,使用
binary32
x=0x1.fffffffep-1:1.0f/x=0x1.000002p+0 1.0f/(1.0f/x)=0x1.fffffff cp-1
binary64
x=0x1.fffffffffffffffffffffffp-1:1:1.0f/x=0x1.000000 1p+0 1.0f/(1.0f/x)=0x1.ffffffffffffffffffffff-1是公认的穷人的反例吗?对于
x=100000
,任何现代CPU都会出现故障,我敢肯定它们是IEEE754投诉…保证的是操作以无限精度进行,然后将结果强制转换为目标值。如果您开始在coarce步骤中引入舍入错误,则再次执行该操作(即使是在无限精度下)将不会产生原始结果。还有,现在你们有很多输入,当你们反转时,它们变得相同,当你们再次反转时,所有这些都会导致不同的输出,这就推翻了你们的论点。什么是不正确的?0.1无法表示,或者将0.1倒转不会产生10?一个设备怎么知道(1/10)-eps应该是1/10而不是近似值?那么1/10的倒数会得到什么呢?倒数0.1(不能用二进制表示。请参阅)。它应该等于1/(0.1+e),其中e是表示错误输入,而不是由于后处理。因此,我概述的测试是否有效取决于实现,取决于情况,有时是对的,有时是错的。(另见:)对不起,假设有缺陷。1/X可以近似,但(1/X)*X也可以近似。现在的问题是,这些近似值总是相互抵消吗。一个反例就足够了。如plasmacel所示,1/10并不是反例。这里一个有趣且易于证明的事实是(假设避免了上溢和下溢,IEEE 754二进制格式,从四舍五入到五舍五入等),分数在
[1.0,sqrt(2)]
范围内的任何浮点
x
都将具有
1.0/(1.0/x)==x的属性。