# How to check positive/zero/negative using bitwise operators -- xpost from Reddit

7 replies to this topic

### #1 jaberwocky6669

jaberwocky6669

Dull light.

• Active Members
• 2,076 posts

Posted 22 September 2012 - 02:37 AM

Sorry if you're a redditor and seen this already. If you know the answer fifteen seconds after reading the question then how about using a spoiler tag in your answer so that you won't ruin it for the rest of us?

Post follows (edited for clarity):

"Given a signed integer, I'm trying to return 1 for positive, 0 for 0, and -1 for negative. The catch is that I can only use bitwise operators (! ~ ^ | + << >>) (and some non bitwise characters too) and I can't declare an integer value greater than 0xFF.
My plan is to right shift 31 places, so the MSB is in the LSB spot. Once there, I perform an &1. If the result is 1, I know I have a negative number. So far I've got:
int sign(int x) {
return ((x>>31)&1);
}

The part that's giving me trouble is getting it to return 1 for a positive number and -1 for a negative number. I've tried countless different solutions, but when it returns the proper value for one it returns the wrong value for the others. I've been working in circles for hours and I'm about to lose my mind. Any help would be appreciated."

### #2 Mat

Mat

43 38 48 31 30 4E 34 4F 32

• MVPs
• 4,040 posts

Posted 22 September 2012 - 05:00 PM

Off the top of my head, something like this would work (if you think 0 is positive):

Spoiler

Shifts are tricky when you are dealing with signed integers. I don't think you can simplify the << and >> into a single >>.

No doubt there are more elegant solutions.

Edit: Just checked the reddit page... There are a lot of rubbish answers not using bitwise operators. I would have expected more people to be able to give a good answer to this question, it really isn't that hard.

Edit: I suspect it isn't possible to get the correct result for zero without using x more than once.

Edit again: Not even this page does it using only bitwise operations: http://bits.stephan-brumme.com/sign.html, is it even possible to negate a 2s complement number using just bitwise?

Edited by Mat, 22 September 2012 - 05:54 PM.

I don't know where I'm going, but I'm on my way.

### #3 Richard Robertson

Richard Robertson

Universalist

• Active Members
• 9,692 posts

Posted 22 September 2012 - 09:37 PM

Why are we doing some reddit user's homework?

### #4 jaberwocky6669

jaberwocky6669

Dull light.

• Active Members
• 2,076 posts

Posted 23 September 2012 - 12:59 AM

Practice. I don't intend to post the solution back to Reddit.

### #5 Mat

Mat

43 38 48 31 30 4E 34 4F 32

• MVPs
• 4,040 posts

Posted 23 September 2012 - 05:44 PM

Given this a fair bit of thought, and this is possible to do using purely bitwise operators, as increment and decrementing are as well provided you know the size of the integers in advance. Quick example of dec is:

```int dec(int x)
{
int i = 1;

for (int c = 0; c < 32; c++)
{
x ^= i;
i = x & i;
i <<= 1;
}

return x;
}```

For those who are about to point out there is a loop, it's just to make it easier to read, it can be unrolled.

Edited by Mat, 23 September 2012 - 05:45 PM.

I don't know where I'm going, but I'm on my way.

### #6 jaberwocky6669

jaberwocky6669

Dull light.

• Active Members
• 2,076 posts

Posted 23 September 2012 - 06:13 PM

It can be unrolled but what about 64 bit systems?

### #7 Mat

Mat

43 38 48 31 30 4E 34 4F 32

• MVPs
• 4,040 posts

Posted 23 September 2012 - 06:26 PM

It can be unrolled but what about 64 bit systems?

It can still be unrolled... Should probably have written: "c < sizeof(int)*8" but as I said, it was a small demo. With this in mind it is possible to negate an integer using just bitwise ops. This means that the method described here is possible using just bitwise ops. Complete code is:

Spoiler

Or slightly shorter and more unreadable:

Spoiler

Just note this really is for academic purposes only. It misses out on all the optimisation usually done by inc, as it processes every bit, regardless of how many need processing.

Edited by Mat, 23 September 2012 - 06:37 PM.

I don't know where I'm going, but I'm on my way.

### #8 Shaggi

Shaggi

Universalist

• Active Members
• 296 posts

Posted 26 September 2012 - 11:46 PM

Well this had me bugged for hours...
relies on some stuff like negatives shifted right will yield -1 at least. have not tested with anything else than x32. also, im not sure this counts since it's using an add operation to determine whether an integer is zero.. maybe this could be computed some other way. but it works so far.
Spoiler
e: typos, formatting, e2: spoilered, e3: reading over assignment again, + is allowed so this solution is valid

Edited by Shaggi, 27 September 2012 - 12:05 AM.

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

#### 0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users