# bit shifting

This is a discussion on bit shifting within the C++ Programming forums, part of the General Programming Boards category; Code: inline UINT32 IsIDXloaded(UINT32 x) { return (x >> 31)&0x00000001;} 1 0000000 11111111 00000000 11111111 am i right when i ...

1. ## bit shifting

Code:
```inline UINT32 IsIDXloaded(UINT32 x)
{ return (x >> 31)&0x00000001;}```
10000000 11111111 00000000 11111111

am i right when i say that this returns the blue bit?

making it
00000000 00000000 00000000 00000001

2. Code:
```x = 0x80000000;
cout<<(x >> 31)&0x00000001;```

3. ## Re: bit shifting

Originally posted by Nor
Code:
```inline UINT32 IsIDXloaded(UINT32 x)
{ return (x >> 31)&0x00000001;}```
10000000 11111111 00000000 11111111

am i right when i say that this returns the blue bit?

making it
00000000 00000000 00000000 00000001
Yes, but the &0x00000001 is completely unnecessary; the shift, coupled with the fact you are using an unsigned type, guarantees bits 1-31 are zeros anyway.

4. ## If you just want to test that bit...

The "normal" way of checking the state (value) of a bit is to BITWISE-AND it with a bit pattern which has a one in that location. You don't need bit-shifting to test a bit.

if(X & 0x80000000) // If this returns zero, bit #31 (your blue bit) is zero.

There is some really good information on bitwise operations in the Programming FAQ ... Just in case you're looking for more info, and haven't seen this part of the FAQ.

5. You should make the return type bool, as well, because that's the ideal return of a function to signal one of two possible states. In fact, return x & 0x80000000; would work just fine, as Doug mentioned, and it's the fastest (and most intuitive) way to do what you want.

6. ## Re: Re: bit shifting

Originally posted by Cat
coupled with the fact you are using an unsigned type, guarantees bits 1-31 are zeros anyway.
if the type was signed which bit would be set?
edit:
bit shifting is supost to be fast right?
so this code should be as quick as it can get?
Code:
```inline bool   IsIDXloaded  (UINT32 x){ return x & 0x80000000;}
inline bool   IsARCloaded  (UINT32 x){ return x & 0x40000000;}
inline UINT32 GetCurrentMod(UINT32 x){ return (x & 0x30000000) >> 28;}
inline bool   GetErrorFlag (UINT32 x){ return x & 0x00080000; }

inline void   SetIDXloaded (UINT32 &x){  x |= 0x80000000; }
inline void   SetARCloaded (UINT32 &x){  x |= 0x40000000; }
inline UINT32 SetCurrentMod(UINT32 &x, UINT32 mod){ mod <<= 30; mod >>= 2; x |= mod; }
////////WARNING////////
// there are 4 possible settings. only 3 are valid.0, 1, 2. if the mod is set to 3 then
// the system will throw an error.
inline void SetErrorFlag      (UINT32 &x){x |= 0x00080000;}
inline void SetError_invalid  (UINT32 &x){x |= 0x00040000;}
inline void SetError_cant_open(UINT32 &x){x |= 0x00020000;}
inline void SetError_bad_file (UINT32 &x){x |= 0x00010000;}
inline void SetError_phras    (UINT32 &x){x |= 0x00008000;}

inline void UnsetErrorFlag      (UINT32 &x){x &= 0xFFF7FFFF;}
inline void UnsetError_invalid  (UINT32 &x){x &= 0xFFFBFFFF;}
inline void UnsetError_cant_open(UINT32 &x){x &= 0xFFFDFFFF;}
inline void UnsetError_bad_file (UINT32 &x){x &= 0xFFFEFFFF;}
inline void UnsetError_phras    (UINT32 &x){x &= 0xFFFFF7FF;}```

7. ## Re: Re: Re: bit shifting

Originally posted by Nor
if the type was signed which bit would be set?
Potentially all of them. If the value is signed, a right shift will sign-extend. For example, if this is a signed 8-bit value:

1000 0000

Shifted right by 3, you'd have

1111 0000

not

0001 0000 (which is what you have if it's unsigned).

If the value is positive (the uppermost bit is zero) then right shifting is the same. Left shifting is always the same.

bit shifting is supost to be fast right?
so this code should be as quick as it can get?
Bitwise operations are very fast, and bit shifting is fast *on many processors*. It depends on the hardware. Modern desktops will use barrel shifters, which means a shift takes very little time. On embedded processors, sometimes they can only shift one bit at a time, so shifting 24 times means 24 separate shifts, to the processor. On an x86, Sun, Mac, etc., shifting is very fast.

8. i typed up my last post without testing it. (was 3am)
this works. the above doesnt.
Code:
```/*
UINT32 m_stat
4    8     12   16    20   24    28   32>>
0000 0000  0000 0000  0000 0000  0000 0000
32   28    24   20    16   12    8    4    <<
First Byte                               Set             Unset
0 - IDX loaded flag;                        0x80 1000 0000  0x7F 0111 1111
1 - ARC loaded flag;                        0x40 0100 0000  0xBF 1011 1111
2 - Current mod. 0-3 2bits;                 0x30 0011 0000  0xCF 1100 1111
3 - ***
4 - error flag. an error occured.           0x08 0000 1000  0xF7 1111 0111
5 - NULL/invalid parameters where givin.    0x04 0000 0100  0xFB 1111 1011
6 - file access error. can not open file.   0x02 0000 0010  0xFD 1111 1101
7 - file access error. bad file             0x01 0000 0001  0xFE 1111 1110
the file could not be validated.

Second Byte
8 - file phrasing error. the file stores    0x80 1000 0000  0x7F 0111 1111
information about itself. some of
this info is not correct.
9 -
*/
//gets
inline bool   GetIDXloaded       (UINT32 x){ return x & 0x80000000;}
inline bool   GetARCloaded       (UINT32 x){ return x & 0x40000000;}
inline UINT32 GetCurrentMod      (UINT32 x){ return(x & 0x30000000) >> 28;}
inline bool   GetErrorFlag       (UINT32 x){ return x & 0x08000000;}
inline bool   GetError_invalid   (UINT32 x){ return x & 0x04000000;}
inline bool   GetError_cant_open (UINT32 x){ return x & 0x02000000;}
inline bool   GetError_bad_file  (UINT32 x){ return x & 0x01000000;}
inline bool   GetError_phras     (UINT32 x){ return x & 0x00800000;}

//sets
inline void   SetIDXloaded (UINT32 &x){  x |= 0x80000000; }
inline void   SetARCloaded (UINT32 &x){  x |= 0x40000000; }
inline void   SetCurrentMod(UINT32 &x, UINT32 mod)
{ mod <<= 30; mod >>= 2; x &= 0xCFFFFFFF; x |= mod; }
////////WARNING////////
// there are 4 possible settings. only 3 are valid.0, 1, 2. if the mod is set to 3 then
// the system will throw an error. Error_invalid

inline void SetErrorFlag      (UINT32 &x){x |= 0x08000000;}
inline void SetError_invalid  (UINT32 &x){x |= 0x04000000;}
inline void SetError_cant_open(UINT32 &x){x |= 0x02000000;}
inline void SetError_bad_file (UINT32 &x){x |= 0x01000000;}
inline void SetError_phras    (UINT32 &x){x |= 0x00800000;}

//unsets
inline void UnsetIDXloaded      (UINT32 &x){x &= 0x7FFFFFFF;}
inline void UnsetARCloaded      (UINT32 &x){x &= 0xBFFFFFFF;}
//line void unsetcourrentmod()
inline void UnsetErrorFlag      (UINT32 &x){x &= 0xF7FFFFFF;}
inline void UnsetError_invalid  (UINT32 &x){x &= 0xFBFFFFFF;}
inline void UnsetError_cant_open(UINT32 &x){x &= 0xFDFFFFFF;}
inline void UnsetError_bad_file (UINT32 &x){x &= 0xFEFFFFFF;}
inline void UnsetError_phras    (UINT32 &x){x &= 0xFFF7FFFF;}```

9. ## what is top bit

The top bit is your sign-bit. It is always the most signficant (highest value) bit.

For example, if I have an unsigned 4-bit number, the high-bit can be used to describe part of the number. In this case:

1111 binary = 8 + 4 + 2 + 1 = 15 decimal. The high-bit is the left-most bit which represents 8 (which is more signficant than the right-hand or low-bit, which only represents a 1).

If this were a "signed" number, the high-bit could only be used to distinguish whether or not the value was a negative one. Necessarily, that subtracts the value of 8 from the maximum number a 4-bit signed number can attain. So then:

1111 binary = sign + 4 + 2 + 1 = -7 decimal.

10. ## Re: what is top bit

Originally posted by Sayeh
The top bit is your sign-bit. It is always the most signficant (highest value) bit.

For example, if I have an unsigned 4-bit number, the high-bit can be used to describe part of the number. In this case:

1111 binary = 8 + 4 + 2 + 1 = 15 decimal. The high-bit is the left-most bit which represents 8 (which is more signficant than the right-hand or low-bit, which only represents a 1).

If this were a "signed" number, the high-bit could only be used to distinguish whether or not the value was a negative one. Necessarily, that subtracts the value of 8 from the maximum number a 4-bit signed number can attain. So then:

1111 binary = sign + 4 + 2 + 1 = -7 decimal.
Actually, that representation of negative numbers (it's called sign-magnitude) is very rare for integers; it makes hardware arithmetic much more complicated. Further, there are two different "zeros" in this system -- positive zero and negative zero.

Most, if not all, modern machines use two's compliment form for negative numbers. Under this representation, a 4-bit signed int with the bits 1111 is actually -1. Using 2's complement:

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = -8
1001 = -7
1010 = -6
1011 = -5
1100 = -4
1101 = -3
1110 = -2
1111 = -1

Two's complement has only one representation for zero, and it can be implemented in hardware much simpler.

Popular pages Recent additions