-1

I am learning bit algorithm and saw the equation that finds the max of two values:

r = x ^ ((x ^ y) & -(x < y)); // max(x, y)

The explanation says this equation will find the max without using comparison and "if x < y, then -(x < y) will be all ones". I cannot comprehend what the explanation means because I see a "less than" operator in the equation and if that is an less than operator, (x < y) should return only one bit of data. Therefore, for the explanation to make sense, the sign "<" cannot be the less than operator. I looked at the list of C operators and did not find other meanings for operator "<". Can someone tell me what does the operator "<" do in this equation? Thanks!

DYZ
  • 55,249
  • 10
  • 64
  • 93
Pracka
  • 159
  • 1
  • 8
  • 1
    It *is* the “less than” operator. `x < y` is either 0 or 1. `-(x < y)` is either 0 or −1. – Ry- Mar 16 '17 at 04:51
  • I see, so -(x – Pracka Mar 16 '17 at 05:05
  • It doesn't find the max "without using comparison", it just uses a comparison in a less straightforward way... so the explanation is questionable. Without using a *conditional*, maybe... – Dmitri Mar 16 '17 at 05:11

2 Answers2

2

This is a very tricky code. The truth is that C does not have any Boolean type: it uses integer instead: 0 for false and 1 for true.

Therefore -(x<y) means

  • 0 if x≥y
  • -1 if x<y

It is then used as a bit mask.

Edit

As suggested by Jonathan Leffler in comments, C has now a _Bool. I made this small program to check what is it and how it is used:

#include <stdio.h>

int main() {  
  _Bool bFalse = 1>2;    
  printf("size of _Bool: %lu\nsize of comparison result: %lu\n", sizeof(bFalse), sizeof(1>2));
  return 0;
}

This outputs:

size of _Bool: 1
size of comparison result: 4

In other words _Bool is one byte (a char), but it is not used as a result of Boolean comparisons (my compiler generates 4 bytes, that is, an int)

Note: tested with Clang on an Intel processor.

Edit: fix the types as kindly suggested in comments (and after checking the clang IR)

Antoine Trouve
  • 1,198
  • 10
  • 21
2

"if x < y, then -(x < y) will be all ones"

This is because, if x is less than y, condition evaluates to true (equal to 1). Notice the negetive sign before comparison, it makes the "1" of comparison result as "-1". In binary world, -1 has an all 1 representation, see Two's_complement. Example: 1111 1111 = -1.

However, if x > y, you get a -0 which is again all zero in binary.

Here, '<' is only a "x is_less_than y" comparison check, a logical operator.

Community
  • 1
  • 1
vishwarajanand
  • 1,021
  • 13
  • 23
  • 1
    C implementations do not all use 2's complement. So we could say that the OP code relies on being run on a 2's complement implementation. – M.M Mar 16 '17 at 05:24