How to check positive/zero/negative using bitwise operators -- xpost from Reddit
#1
Posted 22 September 2012 - 02:37 AM
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."
http://www.reddit.com/r/C_Programming/comments/105von/how_to_check_positivezeronegative_using_bitwise/
RegisterDeviceNotifications | FunctionNameLister | SciTE Customization GUI | MouseHover --> CallTips
#2
Posted 22 September 2012 - 05:00 PM
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
Posted 22 September 2012 - 09:37 PM
#4
Posted 23 September 2012 - 12:59 AM
RegisterDeviceNotifications | FunctionNameLister | SciTE Customization GUI | MouseHover --> CallTips
#5
Posted 23 September 2012 - 05:44 PM
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
Posted 23 September 2012 - 06:13 PM
RegisterDeviceNotifications | FunctionNameLister | SciTE Customization GUI | MouseHover --> CallTips
#7
Posted 23 September 2012 - 06:26 PM
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:It can be unrolled but what about 64 bit systems?
Or slightly shorter and more unreadable:
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
Posted 26 September 2012 - 11:46 PM
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.
Edited by Shaggi, 27 September 2012 - 12:05 AM.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users





