Thread: Bit Shifting Question

  1. #1
    Information Crocodile
    Join Date
    Dec 2004
    Posts
    204

    Bit Shifting Question

    Im currently studying how to manipulate bits. Im getting kinda confused.

    if i have

    Code:
    char i = 64 << 1; // left shift bits one pos to the left
    i >>= 1; // shift back 1 pos to the right, returns to original value 64
    this above works fine returning it back to 64.

    but if the character exceeds 64 it wont go back to its original value.

    Code:
    char i = 66 << 1; // left shift bits one pos to the left
    i >>= 1; // doesnt go back to 64
    And it also fills the 0's(or should be blanks( 0's ) ) with 1's whenever i right shift these over 64 values.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    unsigned char?

    Code:
    char i = 66 << 1; // left shift bits one pos to the left
    i >>= 1; // doesnt go back to 64
    You mean 66, of course. It should work.

    Code:
    66 = 01000010
    
    01000010 << 1 = 
    10000100
    
    10000100 >> 1 =
    01000010
    
    01000010 = 66
    // worked
    What it won't work for is, like, 131 or something:
    Code:
    131 = 10000011
    
    // LSB gets shifted out of existence:
    10000011 << 1 = 
    00000110
    
    00000110 >> 1 =
    00000011
    
    00000011 = 3
    // didn't work
    That's for a char. It would work for an int or a short or something.
    Last edited by dwks; 09-12-2005 at 05:21 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Try an unsigned char instead. You should always use unsigned datatypes for bit fields.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You should always use unsigned datatypes for bit fields.
    No, you can use signed for bitfields. But that's beside the point. loko is using a char here (which, as we both pointed out, should be an unsigned char).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Information Crocodile
    Join Date
    Dec 2004
    Posts
    204
    Code:
     01000010 = 66   // Thats what i was expecting but instead the binary pattern became 11000010 not 01000010, the 0 at the leftmost part became 1.
    // worked

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That's because it isn't unsigned!
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Information Crocodile
    Join Date
    Dec 2004
    Posts
    204
    Quote Originally Posted by dwks
    That's because it isn't unsigned!

    Works fine now Whats the difference in using unsigned char and char?

  8. #8
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    The good book says:
    The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
    or if E1 has a signed type and a nonnegative value, the value of the result is the integral
    part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the
    resulting value is implementation-defined.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well, in a signed char, the LSD bit (Least Significant Bit, the bit on the left) is used to indicate the sign. If it's 1, the number is negative.
    Code:
    Signed char values:
    0: 00000000
    -1: 11111111
    -2: 11111110
    -3: 11111101
    -5: 11111011
    etc.
    I think when you >> 1 a signed number the LSB becomes 1, although I don't really know.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Shifting right one positon is often used to divide a number by two. That is why when shifting right negative numbers the MSB is filled with 1 to get the right result. Alwais thought that this is what should happen with standard conforming compilers but hammer pointed out that this is implementation-defined.
    Try this:
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    string byte_to_bin(unsigned char c) {
       unsigned char mask = 0x80;
       string ret;
       for ( int i = 0; i < 8; ++i ) {
          ret += ( c & mask ? "1": "0"); mask >>= 1;
       }
       return ret;     
    }
    
    int main() {
       char c = -118;
       cout << setw(4) << (int)c << " ( " << byte_to_bin(c) <<" ) >> 1 = ";
       c >>= 1;
       cout << setw(4) << (int)c << " (" << byte_to_bin(c) << ")" << endl;
       c = 62;
       cout << setw(4) << (int)c << " ( " << byte_to_bin(c) <<" ) >> 1 = ";
       c >>= 1;
       cout << setw(4) << (int)c << " (" << byte_to_bin(c) << ")" << endl;
    }
    I get this output with g++
    Code:
    -118 ( 10001010 ) >> 1 =  -59 (11000101)
      62 ( 00111110 ) >> 1 =   31 (00011111)
    Kurt
    edit: sorry that I posted C++ code in the C-Forum

  11. #11
    Information Crocodile
    Join Date
    Dec 2004
    Posts
    204
    Quote Originally Posted by ZuK
    Shifting right one positon is often used to divide a number by two. That is why when shifting right negative numbers the MSB is filled with 1 to get the right result. Alwais thought that this is what should happen with standard conforming compilers but hammer pointed out that this is implementation-defined.
    Try this:
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    string byte_to_bin(unsigned char c) {
       unsigned char mask = 0x80;
       string ret;
       for ( int i = 0; i < 8; ++i ) {
          ret += ( c & mask ? "1": "0"); mask >>= 1;
       }
       return ret;     
    }
    
    int main() {
       char c = -118;
       cout << setw(4) << (int)c << " ( " << byte_to_bin(c) <<" ) >> 1 = ";
       c >>= 1;
       cout << setw(4) << (int)c << " (" << byte_to_bin(c) << ")" << endl;
       c = 62;
       cout << setw(4) << (int)c << " ( " << byte_to_bin(c) <<" ) >> 1 = ";
       c >>= 1;
       cout << setw(4) << (int)c << " (" << byte_to_bin(c) << ")" << endl;
    }
    I get this output with g++
    Code:
    -118 ( 10001010 ) >> 1 =  -59 (11000101)
      62 ( 00111110 ) >> 1 =   31 (00011111)
    Kurt
    edit: sorry that I posted C++ code in the C-Forum
    Now i understand thnks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bit level permutation function
    By zxcv in forum C Programming
    Replies: 2
    Last Post: 07-27-2008, 01:26 PM
  2. bit shifting uint8_t
    By kdoggfunkstah in forum C++ Programming
    Replies: 8
    Last Post: 07-28-2006, 03:38 AM
  3. bit shifting a mask
    By detfella in forum C++ Programming
    Replies: 1
    Last Post: 02-25-2004, 05:13 PM
  4. quick question about bit manipulation
    By PJYelton in forum C++ Programming
    Replies: 7
    Last Post: 01-10-2003, 01:18 AM
  5. bit shifting
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 07-14-2002, 12:31 AM