For this you need someone to teach it to you: if you made it yourself, then you are a very good Comp-Sci, and you should send your CV to Google ASAP. ;)

Without branching O_o?

Yes, without using any “if ( a < 0 )…”. To do that, you need to refresh how Two’s Complement works, then come back.

What we really need to focus on is that, given a signed int A, the negative of that number is: B = ~A + 1. BUT, we are trying to calculate the Absolute Value, not the negative. So, something like:

1
2
3
4
RESULT =
    (INPUT, if positive, or NEGATE_INPUT, if negative)
    +
    (0, if positive, or 1, if negative)

Does it makes sense to you? To me it didn’t for the first 10 minutes.

What do we need?

We need, given the integer in input, to calculate 2 values:

  • A way to “optionally negate” the input

  • A variable carrying 0 if the input is positive, 1 otherwise

Look what we have here: the XOR

Properties of XOR are:

  • A ^ 0 = A

  • A ^ 1 = ~A

  • A ^ A = 0

  • A ^ B = B ^ A (commutative)

The first two properties are key here: if we could only generate a variable from the input that contains 0 if positive and 1 if negative, we would have half hack done.

Ladies and Gentleman, all shift please

Now, let’s see some shifting in action. If A is a Positive number, then:

1
2
A = INPUT >> 31 => 0x00000000 => 0
B = -A => -0x00000000 => 0

While if A is a Negative number, then:

1
2
A = INPUT >> 31 => 0xFFFFFFFF => -1
B = -A => 0x00000001 => 1

Putting all together

So, this means that we can calculate the absolute value using the new variables we have produced, A and B. Here is how:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdio.h>

int abs(const int value) {
   int A = value >> 31;     // 0x00000000 if Positive, 0xFFFFFFFF if Negative
   int B = -A;              // 0x00000000 if Positive, 0x00000001 if Negative
   return (value ^ A) + B;  // value ^ A = value if Positive, value ^ A = ~value if Negative
}

int main(int argc, char** argv)
{
    int input;
    
    // Check the Input
	if ( argc == 2 ) input = atoi(argv[1]); else return (1);
	
	printf("abs(%d) = %d\n\n", input, abs(input));
}

Who showed me this hack? eh eh eh! ;)