Thread: bit shifting

  1. #1
    ‡ †hë Ö†hÈr sîÐè ‡ Nor's Avatar
    Join Date
    Nov 2001
    Posts
    299

    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
    Try to help all less knowledgeable than yourself, within
    the limits provided by time, complexity and tolerance.
    - Nor

  2. #2
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Code:
    x = 0x80000000;
    cout<<(x >> 31)&0x00000001;
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    1,619

    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. #4
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398

    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.
    Last edited by DougDbug; 08-06-2003 at 02:15 PM.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    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. #6
    ‡ †hë Ö†hÈr sîÐè ‡ Nor's Avatar
    Join Date
    Nov 2001
    Posts
    299

    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;}
    Last edited by Nor; 08-07-2003 at 08:31 AM.
    Try to help all less knowledgeable than yourself, within
    the limits provided by time, complexity and tolerance.
    - Nor

  7. #7
    Registered User
    Join Date
    May 2003
    Posts
    1,619

    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. #8
    ‡ †hë Ö†hÈr sîÐè ‡ Nor's Avatar
    Join Date
    Nov 2001
    Posts
    299
    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;}
    Try to help all less knowledgeable than yourself, within
    the limits provided by time, complexity and tolerance.
    - Nor

  9. #9
    Visionary Philosopher Sayeh's Avatar
    Join Date
    Aug 2002
    Posts
    212

    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.
    It is not the spoon that bends, it is you who bends around the spoon.

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    1,619

    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.
    Last edited by Cat; 08-08-2003 at 11:57 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  2. bit value check efficiency
    By George2 in forum C Programming
    Replies: 5
    Last Post: 11-05-2007, 07:59 AM
  3. Quick question regardin bit shifting
    By shoobsie in forum C Programming
    Replies: 10
    Last Post: 11-04-2005, 10:46 AM
  4. bit patterns of negtive numbers?
    By chunlee in forum C Programming
    Replies: 4
    Last Post: 11-08-2004, 08:20 AM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM