Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are float inequalities guaranteed to be consistent

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.

like image 972
not-a-user Avatar asked Jun 29 '15 06:06

not-a-user


2 Answers

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...

like image 82
Serge Rogatch Avatar answered Nov 14 '22 12:11

Serge Rogatch


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.

like image 21
tmyklebu Avatar answered Nov 14 '22 11:11

tmyklebu