浮动不平等是否保证一致

not*_*ser 18 c c++ floating-point

假设a,b,c,和d声明double(或float).以下表达式是否始终为真?

! ( (a >= b) && (c <= d) ) || ( (a-c) >= (b-d) )

! ( (a >  b) && (c <= d) ) || ( (a-c) >  (b-d) )

! ( (a >= b) && (c <  d) ) || ( (a-c) >  (b-d) )
Run Code Online (Sandbox Code Playgroud)

IEEE 754或当前的C或C++标准是否有任何保证?任何编译器都会在编译时将其优化为真的吗?我主要对正常值感兴趣,而不是在低于正常值或特殊值.

在我看来,这应该主要取决于减法期间的舍入误差.

Ser*_*tch 10

对于第三个生产假就应该足够服用大平等ab小不平等cd,如a=1e30, b=1e30, c=1e-31, d=1e-30.

编辑:好的,第2个到产生错误,类推到第三,它应该足以采取小不平等ab大平等cda=1e-30, b=1e-31, c=1e30, d = 1e30.

不知道第一个表达的反例......

  • 对于#1 [demo](http://ideone.com/oXmPXP),将abc和d设置为+ Infinity会产生错误,但我猜这不算数,因为它是一个"特殊"值 (4认同)

tmy*_*ebu 7

Serge Rogatch给你的第二和第三个表达提供了反例.

第一个,!(a >= b && c <= d) || a-c >= b-d在IEEE 754算术中总是如此,如果a,bc,并且d必须都是有限的.减去有限数不能产生一个NaN.因此,一个反例必须满足a >= b && c <= d && a-c < b-d.然而,a >= b意味着a-c >= b-c,无论c是什么,并c <= d暗示b-c >= b-d,无论b是什么.>=照顾其余的传递性.

您可以a = c = 1.0/0.0采取的任意选择,b并且d,如果你放松的条件一个反例a,b,c,并且d必须是有限的.所有反例基本上都是这种形式.