Reputation: 140
https://www.geeksforgeeks.org/compute-the-minimum-or-maximum-max-of-two-integers-without-branching/
I was trying to find alternative ways of finding maximum and minimum between two integer and came across the following code which is used for the operation.can anyone please clarify the working and role of the bitwise operator in the code:
/*Function to find minimum of x and y*/
int min(int x, int y)
{
return y ^ ((x ^ y) & -(x < y));
}
/*Function to find maximum of x and y*/
int max(int x, int y)
{
return x ^ ((x ^ y) & -(x < y));
}
Upvotes: 4
Views: 3813
Reputation: 224437
First let's look at this part:
-(x < y)
If the conditional is true, i.e. if x
is less than y
, than the parenthesized expression is 1 and the whole expression is -1. If the conditional is false then the expression has the value 0.
Now let's look at it in the context of the next level subexpression:
((x ^ y) & -(x < y))
Based on the above condition, this will reduce to one of the following:
((x ^ y) & 0) // x is larger or equal
((x ^ y) & -1) // y is larger
Performing a bitwise AND with 0 results in all bits of the result being 0, so the first expression will be 0. The value -1, assuming two's complement representation, has all bits set to 1. So performing a bitwise AND with -1 will result in the value of the other operand.
So now looking at the full expression for max
:
x ^ ((x ^ y) & -(x < y))
This translates to:
x ^ (0) // x is larger or equal
x ^ (x ^ y) // y is larger
In the first case, performing an XOR with 0 results in the value of the other operand so the final result is x
. In the second case, ^
is associative so you can look at it as (x ^ x) ^ y
XORing a number with itself results in 0, and XORing 0 with y
gives you y
.
The min
function works similarly with y
in place of x
for the first operand:
y ^ (0) // x is larger or equal
y ^ (x ^ y) // y is larger
This will give the opposite result of max
.
Upvotes: 4
Reputation: 370407
return y ^ ((x ^ y) & -(x < y));
-(x < y)
will be 0 if x >= y
and -1 (i.e. an int with all bits set) if x < y
. Note that foo & -1 == foo
and foo & 0 == 0
for all foo
. So if x < y
, we get y ^ x ^ y
, which is equal to x
because y ^ y
cancels out. And otherwise we get y ^ 0
, which is y
. So we get x
if x < y
and y
otherwise, which is exactly what you'd want from a function named min
.
For max
it's the same thing, except we return y
if x < y
and x
otherwise.
Upvotes: 6