tags:

views:

299

answers:

10

Say I wanted to test not just one, but several variables for equivalence in an if statement:

if(x1==x2==y1==y2){
    printf("Input values shouldn't be equal!");
}

But this doesn't seem to work. What other approach can do this?

A: 

Doesn't work because (x1 == x2) evaluates to the number 1, if true, and 0 if false, by the way. (x1 == x2 == x3) ends up evaluating as ((x1 == x2) == x3).

You'd need to write your own function to do this, I think.

M1EK
Would upvote for the correct explanation, but it doesn't require a separate function, can be done inline.
Josh W.
My comment about the function was for a general purpose solution, i.e. test N things for equality. Obviously you can write out the 3 variable case inline.
M1EK
+8  A: 
if( x1 == x2 && x2 == y1 && y1 == y2 ) { ... }
AraK
+1: Easier to understand that the code is looking for all of them equal.
John R. Strohm
+9  A: 
if (x1 == x2 && x1 == y1 && x1 == y2)
{
  printf("Input values shouldn't be equal!");
}
Sani Huttunen
A: 

Your problem is the incorrect usage of the == operator. You would need to use something like:

if ((x1 == x2) && (x1 == y1) && (x1 == y2)) {
   printf("Input values shouldn't be equal!"); 
}
Josh W.
The problem is not precedence, it's that `==` doesn't do the same thing in C as `=` does in Lisp. Making it work that way would require more than a change in precedence.
David Thornley
Updated my answer, better?
Josh W.
Much better, thanks.
David Thornley
A: 
if(x1==x2 && x1 == y1 && x1 == y2 && 
      x2==y1 && x2 == y2 &&
       y1 == y2)
{ printf("Input values shouldn't be equal!"); }
  return 0;
}
aJ
All what you need is 3 equality tests, your boolean expression can be simplified ;)
AraK
No need to check all six permutations.
Sani Huttunen
yes, it's over-the-top.. but its NOT wrong!
warren
+24  A: 
if (x1 == x2 && x2 == y1 && y1 == y2) { ... }

The result of the expression a == b will be an integer value of either 0 or 1. the == operator is left-associative, so the expression a == b == c will be evaluated as (a == b) == c; that is, the result of a == b (0 or 1) will be compared against the value of c. So in the code below

if (a == b == c) { ... }

the expression will only evaluate to true if a == b and c == 1 or a != b and c == 0.

John Bode
excellent!!! I just wish I could add more.
Dave
+3  A: 

Here's a different approach, using a helper variable ( count_equals ) so that it's easy to do (and understand) exactly what you want.

int count_equals = 0;
if (x1 == x2) count_equals++;
if (x1 == y1) count_equals++;
if (x1 == y2) count_equals++;
if (x2 == y1) count_equals++;
if (x2 == y2) count_equals++;
if (y1 == y2) count_equals++;

if (count_equals == 0) /* all values are different */;
else if (count_equals == 6) /* all values are equal */;
else /* some values are equal */;
pmg
Very helpful and illustrative. Thankyou
Fergus
+5  A: 

if they are integers you can use bitwise operations:

if ((x1 & x2 & x3 & x4) == (x1 | x2 | x3 | x4))
  // all are equal

It will evaluate to true IFF they are all the same

rmn
really nice! I thought about something similar - but you where faster.
+1  A: 

The solutions presented here where mostly correct and easy to understand.

But I would prefer the solution provided by Sany Huttunen:

quoted:

if (x1 == x2 && x1 == y1 && x1 == y2)
{
  printf("Input values shouldn't be equal!");
}

Here is the reason why:

Although it seems not to be possible in this concrete case it directed me immediately into thinking about refactoring, like in:

(a*b) + (a*c) + (a*d)

which could be simplified into

a*(b+c+d)

as mentioned it's not possible to simplify in this concrete case however, because

(a*b) + (a*c) + (a*d)

follows different mathematical rules then

(a+b) * (a+c) * (a+d)

This has something to do with commutative, associative and distributive rules if I remember correctly.

Extra points for generalization.
Fergus
A: 

Here is another method using Boolean logic

bool all_equal(false)
all_equal = x1 == x2;
all_equal = all_equal && (x2 == x3);
all_equal = all_equal && (x3 == x4);

A good compiler can code this using conditional assembly instructions and not disrupt the instruction prefetch queue.

Thomas Matthews