#170637 - brave_orakio - Fri Oct 09, 2009 2:25 am
Hi guys. A question.
Which bit contains the information for the sign of an int? I want to use some bitwise operations to brinmg down a signed integer to 3 values. -1, 0 and 1.
if it was just 0 and 1 all I do is
So this becomes either 0 or 1 no problem. but this
doesn't seem to work so I decided to try to preserve the bit containing the sign first before working on the rest of the integer.
_________________
help me
#170638 - elhobbs - Fri Oct 09, 2009 2:58 am
-1 is 0xFFFFFFFF. So, anything & -1 will equal the original value. & 0x80000000 will test for negative on a 32bit signed int.
edit: changed "&=" to "&"
Last edited by elhobbs on Fri Oct 09, 2009 5:50 pm; edited 1 time in total
#170640 - brave_orakio - Fri Oct 09, 2009 5:23 am
Thanks, I'll try that out!
_________________
help me
#170666 - keldon - Sat Oct 10, 2009 8:42 am
If you absolutely must:
Code: |
#define IS_ZERO( v ) ( !(v) )
#define IS_NEGATIVE( v ) ( u32( (v) ) >> 31 )
#define IS_POSITIVE( v ) ( IS_NEGATIVE( -(v) ) && !IS_ZERO( (v) ) )
intVal = IS_POSITIVE( intVal ) - IS_NEGATIVE( intVal ); |
#170668 - brave_orakio - Sat Oct 10, 2009 9:42 am
Nice! thanks! Another question though, because I ran into something nasty with my divides:
why is this -1?
shouldn`t it be equal to 0?
_________________
help me
#170669 - Cearn - Sat Oct 10, 2009 12:32 pm
brave_orakio wrote: |
shouldn`t it be equal to 0?
|
No. Bit-shifts are still primarily bit-shifts. That you can use them in a division-like capacity is just an accident of how numbers are represented. In negative numbers, the higher bits are all 1. When you shift-right, these shift into the lower bits. If you shift out all the 'real' bits of a number, the result is all 1s, that is, 0xFFFFFFFF == -1. Effectively, div-by-rightshift always rounds to -infinity (whereas normal integer division rounds to 0).
Code: |
// In 16 bits
-54 = 0xFFCA = 1111 1111 1100 1010
1111 1111 1100 1010 >> 6 = 1111 1111 1111 1111 = -1.
|
keldon wrote: |
Code: |
#define IS_POSITIVE( v ) ( IS_NEGATIVE( -(v) ) && !IS_ZERO( (v) ) ) |
|
Note that the IS_ZERO part doesn't actually do anything here and can safely be removed. For a threeway sign, this is enough:
Code: |
//! Returns -1 for x<0, 0 for x==0, and +1 for x>0.
static inline int sign3(int x)
{ return (x>>31) - (-x>>31 ); }
|
#170670 - keldon - Sat Oct 10, 2009 12:59 pm
--- never mind ---
But yes, 0 >> 31 == 0; duh!
#170683 - brave_orakio - Mon Oct 12, 2009 3:03 am
Ah, I see, thanks!
_________________
help me
#170861 - elyk1212 - Sat Oct 24, 2009 2:10 am
Yeah. If you're variable is a regular int, shifting is signed. So you can right shift till the cows come home, and you'll still get a 1 in the MSB (the sign bit).
But.... If it is an unsigned variable, the >> and << will translate to an unsigned shift operation, you were perhaps expecting.
So maybe as an exercise in fun:
try:
Code: |
int si = -something;
unsigned int i = -something;
|
and try printing these out after/during some shift operations and see the difference.
_________________
"Turn from evil and do good; seek peace and pursue it." Psalm 34:14
Like art? Just some wallpapers I do in my free time:
http://www.razzlegames.com/wallpaper/