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
对于第三个生产假就应该足够服用大平等a
和b
小不平等c
和d
,如a=1e30, b=1e30, c=1e-31, d=1e-30
.
编辑:好的,第2个到产生错误,类推到第三,它应该足以采取小不平等a
和b
大平等c
和d
如a=1e-30, b=1e-31, c=1e30, d = 1e30
.
不知道第一个表达的反例......
Serge Rogatch给你的第二和第三个表达提供了反例.
第一个,!(a >= b && c <= d) || a-c >= b-d
在IEEE 754算术中总是如此,如果a
,b
和c
,并且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
必须是有限的.所有反例基本上都是这种形式.