Floating point 浮点稳定性

Floating point 浮点稳定性,floating-point,Floating Point,假设我有两个相等的有理分数a/b和c/d。a、 b、c和d都可以表示为32位有符号整数。如果我用64位浮点数除法,a/b==c/d是否总是?在某些情况下,即使结果保证相同,编译器优化也会阻止相等为真。最初的x86浮点运算在80位寄存器上执行;如果将其中一个与存储的64位值进行比较,它可能会比较不相等。如果要测试相等性,可以使用64位整数并将(ad)与(bc)进行比较,从而完全避免整个浮点舍入问题。例如,1/2和3/6肯定会不同。1/2和3/6不会不同,为什么会这样?无论使用何种精度(浮动双扩展…

假设我有两个相等的有理分数a/b和c/d。a、 b、c和d都可以表示为32位有符号整数。如果我用64位浮点数除法,a/b==c/d是否总是?

在某些情况下,即使结果保证相同,编译器优化也会阻止相等为真。最初的x86浮点运算在80位寄存器上执行;如果将其中一个与存储的64位值进行比较,它可能会比较不相等。

如果要测试相等性,可以使用64位整数并将(ad)与(bc)进行比较,从而完全避免整个浮点舍入问题。例如,1/2和3/6肯定会不同。1/2和3/6不会不同,为什么会这样?无论使用何种精度(浮动双扩展…),它们都将精确(1/2)。双精度(1)/双精度(3)和双精度(5)/双精度(15)也会导致与num.和den相同的结果。精确转换后,IEEE/的结果是根据舍入规则(和模式)精确舍入的分数。如果使用中间扩展精度,则执行第二次四舍五入以加倍。。。双精度(1/extended(3))可能与1/double(3)不同。。。如果两个分数都经过相同的舍入阶段,结果应该是相同的。如果能够看到一些显示此问题的代码,那就太好了。我曾尝试在java中执行此操作,但似乎无法强制将64位与80位值进行比较。Intel目标有多个编译器,它们并不都使用80位值实现浮点运算。@EricPostChil,你说得对-现代编译器可能使用SSE实现浮点,并完全避免使用80位寄存器。因为问题是关于“总是”的,我觉得一个反例就足够了。@benmmurphy,Java可能没有遇到这个问题,要么是因为它不使用旧的80位浮点指令,要么是因为它总是在比较结果之前存储结果。比较前不需要“存储”结果;只需使用双精度(给定双精度操作数)计算周期。