get absolute value without using abs function nor if statement
I was thinking how to get the absolute value of an integer without using if
statement nor abs()
. At first I was using shift bits left (<<
), trying to get negative sign out of the range, then shift bits right back to where it be, but unfortunately it doesn't work for me. Please let me know why it isn't working and other alternatives ways to do it.
From Bit Twiddling Hacks:
int v; // we want to find the absolute value of v
unsigned int r; // the result goes here
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
r = (v + mask) ^ mask;
int abs(int v)
{
return v * ((v>0) - (v<0));
}
This code multiplies the value of v
with -1
or 1
to get abs(v). Hence, inside the parenthesis will be one of -1
or 1
.
If v
is positive, the expression (v>0)
is true and will have the value 1
while (v<0)
is false (with a value 0 for false). Hence, when v
is positive ((v>0) - (v<0)) = (1-0) = 1
. And the whole expression is: v * (1) == v
.
If v
is negative, the expression (v>0)
is false and will have the value 0
while (v<0)
is true (value 1). Thus, for negative v
, ((v>0) - (v<0)) = (0-1) = -1
. And the whole expression is: v * (-1) == -v
.
When v == 0
, both (v<0)
and (v>0)
will evaluate to 0, leaving: v * 0 == 0
.
Branchless:
int abs (int n) {
const int ret[2] = { n, -n };
return ret [n<0];
}
Note 4.7 Integral Conversions / 4: [...] If the source type is bool, the value false is converted to zero and the value true is converted to one.
I try this code in C, and it works.
int abs(int n){
return n*((2*n+1)%2);
}
Hope this answer will be helpful.
Assuming 32 bit signed integers (Java), you can write:
public static int abs(int x)
{
return (x + (x >> 31)) ^ (x >> 31);
}
No multiplication, no branch.
BTW, return (x ^ (x >> 31)) - (x >> 31);
would work as well but it is patented. Yup!
Note: This code may take more then 10x longer then conditional statement (8bit Verison). This may be useful for Hardware programming System C etc