c/d" is not always = "ad>bc", for example: a=20, b=5, c=9..." /> c/d" is not always = "ad>bc", for example: a=20, b=5, c=9..." /> c/d" is not always = "ad>bc", for example: a=20, b=5, c=9..."/>

How to eliminate division inside code like "a/b>c/d"?

134 views Asked by At

For example, if I don't want division in "a/b==c/d",I can rewrite it as "ad==bc".

But "a/b>c/d" is not always = "ad>bc", for example:

a=20, b=5, c=9,d=3 : a/b>c/d is true and ad>bc is true

but

a=-20, b=-5, c=9,d=3 : a/b>c/d is true but ad>bc is false

I started to found the patten, it seems (I am not sure if it is right):

if b and d has same sign, a/b>c/d = ad > bc

if b and d has different sign, a/b > c/d = ad < bc

if I rewrite "a/b>c/d" as

(( (b>0 && d>0 || b<0 && d<0) && a*d>b*c) || ( ((b>0 && d<0) || b<0 && d>0) && a*d<b*c)

,it needs type more characters, also I need to type each variable more than 1 time,and this form is very hard to maintain if I want to change to

a/b>=c/d 

or

a/b<c/d

Is there any method to eliminate division in a/b>c/d in simpler way?

3

There are 3 answers

0
samgak On BEST ANSWER

You can rewrite it as:

a*d*b*d > b*c*b*d

This way if b and d have different signs then b*d will be a negative number and the comparison will be flipped back the correct way. Be careful about overflows however. To make the code equivalent to a/b > c/d you will also need to check if b or d are zeros.

0
Michael Anderson On

When you multiply both sides of an inequality by some non-zero number v, then if v is negative you must reverse the direction of the inequality.

So in your case you are multiplying by b*d so

if (a/b > c/d) {
 ...
}

is equivalent to

v = b * d;
if(v==0) {
  error
}

if ( ( (v>0) && (a*d > c*b) ) || 
     ( (v<0) && (a*d < c*b) ) ) {
   ...
}

If you don't care whether you're using > or >=, or care about the handling of v==0 you can rewrite this as

if ( (v>0) ^ (a*d > c*b ) ) {
  ...
}

There's further considerations required if a, b, c and d are floating point numbers as you need to consider the behaviour of positive and negative infinity, signed zeros and "not a number" values.

0
Dectinc On

May be you can get the signs of b and d by bitwise operation, and then rewrite "a/b>c/d" as

(((b>>31)&1) ^ ((d>>31)&1)) ^ (ad > bc)

which is equivalent to

((b>0) ^ (d>0)) ^ (ad > bc)

say b and d are 32-bits integers