Reputation: 1345
Using only bitwise operators (|, &, ~, ^, >>, <<) and other basic operators like +, -, and !, is it possible to replace the "==" below?
int equal(int x, int y) {
return x == y;
}
Upvotes: 29
Views: 45486
Reputation: 41
As XOR is same as (!=), hence (x ^ y) will return 0 only for equal values. My take is the following because it is sensible, uses bit-wise operator and working.
int notEqual(int x, int y){
return (x ^ y);
}
Upvotes: 2
Reputation: 798804
Remember that an XOR
is the exactly same as NOT EQUALS
and XNOR
is exactly the same as EQUALS
. So, the following will give you exactly what you want:
return !(x ^ y);
Upvotes: 84
Reputation: 3870
My Take on this
int equal(int x, int y){
if((x & ~y) == 0)
return 1;
else
return 0;
}
Explanation: If x == y
, then x & ~y
evaluates to 0
return 1, else return 0 as x!=y
.
Edit1: The above is equivalent to
int equal(int x, int y){
return !(x & ~y) ; // returns 1 if equal , 0 otherwise.
}
The above code fails in certain cases where the Most significant bit turns to 1. The solution is to add a 1. i.e correct answer is
return !(x & (~y +1) );
Upvotes: 0
Reputation: 3311
The C !
operator is really just shorthand for != 0
, so using it seems very close to cheating :)
Here's my take just using bitwise operations, assuming a 32-bit two's complement machine with arithmetic right shifts (technically, in C arithmetic right shifts are undefined, but every C compiler I've ever seen on a two's complement machine supports this correctly):
int t = (x - y) | (y - x); // <0 iff x != y, 0 otherwise
t >>= 31; // -1 iff x != y, 0 otherwise
return 1 + t; // 0 iff x != y, 1 otherwise
That said, actual compilers don't have this problem. Real hardware actually has direct support for comparisons. The details depend on the architecture, but there's two basic models:
More RISC-like platforms typically have direct "branch if equal" and "branch if less than" operands that do a comparison and branch based on the result. It's basically equivalent to the C code
if (a == b) goto label;
or
if (a < b) goto label;
all in one machine instruction.
Upvotes: 20
Reputation: 17866
This example is the same as subtraction, but is more explicit as to how some architectures do register comparison (like the ARM, I believe).
return !(1 + ~x + y);
The 1 signifies the carry-bit input into the ALU. One number x
is bitwise complemented. Taking the complement and adding 1 produces the two's complement of the number (x
becomes -x
), and then it's added to the other number to get the difference to determine equality.
So if both numbers are equal, you get -x + x => 0
.
(On a register level the !
operator isn't done, and you just test the "zero bit" of the condition codes or flags register, which gets set if the register operation produces a result of zero, and is clear otherwise.)
Upvotes: 3
Reputation: 229663
Two numbers are equal if there is no difference between them:
int equal(int x, int y){
return !(x-y);
}
Upvotes: 26