假设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) )
IEEE754或当前的C或C++标准有什么保证吗?会不会有编译器在编译时将其优化为真呢?我最感兴趣的是正常值,而不是不正常的或特殊的值。
在我看来,这主要取决于减法过程中的舍入误差。
发布于 2015-06-29 15:12:55
对于第三个产生false,应该足够大的相等的a
和b
和小的不相等的c
和d
,例如a=1e30, b=1e30, c=1e-31, d=1e-30
。
编辑:好的,第二个产生false,类推到第三个,取小的不相等的a
和b
,以及大的相等的c
和d
,例如a=1e-30, b=1e-31, c=1e30, d = 1e30
。
不知道第一个表达式的反例...
发布于 2015-06-29 20:11:24
Serge Rogatch对你的第二个和第三个表达式给出了反例。
如果a
、b
、c
和d
都必须是有限的,则第一个参数!(a >= b && c <= d) || a-c >= b-d
在IEEE754算法中总是正确的。有限数的减法不能产生NaN
。因此,反例必须满足a >= b && c <= d && a-c < b-d
。然而,a >= b
暗示a-c >= b-c
,不管c
是什么,c <= d
暗示b-c >= b-d
,不管b
是什么。>=
的传递性解决了剩下的问题。
如果放宽a
、b
、c
和d
都必须是有限的条件,您可以以a = c = 1.0/0.0
为例,并以任意选择b
和d
作为反例。所有的反例基本上都是这种形式。
https://stackoverflow.com/questions/31109417
复制相似问题