Assume a
, b
, c
, and d
are declared double
(or float
). Are the following expressions always true?
! ( (a >= b) && (c <= d) ) || ( (a-c) >= (b-d) )
! ( (a > b) && (c <= d) ) || ( (a-c) > (b-d) )
! ( (a >= b) && (c < d) ) || ( (a-c) > (b-d) )
Is there any guaranty from the IEEE 754 or the current C or C++ standard? And will any compiler optimize this as simply true at compile time? I am interested mostly in normal values, not so much in subnormal or special values.
Seems to me this should depend on round-off errors during subtraction mostly.
For the 3rd to produce false it should be sufficient to take large equal a
and b
and small unequal c
and d
, e.g. a=1e30, b=1e30, c=1e-31, d=1e-30
.
EDIT: Ok, for the 2nd to produce false, by analogy to the 3rd, it should be sufficient to take small unequal a
and b
and large equal c
and d
, e.g. a=1e-30, b=1e-31, c=1e30, d = 1e30
.
No idea about a counterexample for the 1st expression...
Serge Rogatch gave counterexamples to your second and third expressions.
The first one, !(a >= b && c <= d) || a-c >= b-d
, is always true in IEEE 754 arithmetic, if a
, b
, c
, and d
must all be finite. Subtraction of finite numbers cannot produce a NaN
. Thus a counterexample must satisfy a >= b && c <= d && a-c < b-d
. However, a >= b
implies that a-c >= b-c
, whatever c
is, and c <= d
implies that b-c >= b-d
, whatever b
is. Transitivity of >=
takes care of the rest.
You can take a = c = 1.0/0.0
and take arbitrary choices of b
and d
for a counterexample if you relax the condition that a
, b
, c
, and d
must all be finite. All counterexamples are of essentially this form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With