Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sign function in C using bit operators only

I'm trying to implement a sign function using only bitwise operators. I know that if I just want to extract the sign bit of a signed integer, I can do: (x >> 31) & 1.

Also, I understand that conditionals can be written as boolean expressions:

if(x) a=y else a=z which is equivalent to a = x ? y:z can be rewritten as:

a=( (x<<31) << 31 ) & y + ( !x << 31) >> 31) & z, assuming x=1 or 0.

This problem gets a little tricky though because I have 3 conditional scenarios:
return 1 if positive, 0 if zero, and -1 if negative.

I was thinking that in order to do this properly, I need to use ! operator and the fact that !0x<nonzero #>=0, !0x0=1, !0x1=0.

So I came up with something like this, which is incorrect:

/*                                                                              
 * sign - return 1 if positive, 0 if zero, and -1 if negative                   
 *  Examples: sign(130) = 1                                                     
 *            sign(-23) = -1                                                    
 *  Legal ops: ! ~ & ^ | + << >>                                                                          
 */
int sign(int x) {
    return (x>>31) & -1 ) + ( !( !x >> 31 ) & 1;
}

I think I have all the pieces but just not quite sure how to put them all together. Any help is appreciated.

Thank you.

like image 987
user1527227 Avatar asked Dec 25 '22 06:12

user1527227


1 Answers

The bit hacks page suggests this expression:

sign = (v != 0) | (v >> 31);

It can be rewritten without != like this:

sign = (!!v) | (v >> 31);

(demo on ideone).

I prefer this expression that does not use bit manipulation, though (from the same page).

sign = (v > 0) - (v < 0);
like image 61
Sergey Kalinichenko Avatar answered Jan 10 '23 18:01

Sergey Kalinichenko