# Bit Shifting Question

• 09-12-2005
loko
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.
• 09-12-2005
dwks
unsigned char?

Quote:

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.
• 09-12-2005
itsme86
Try an unsigned char instead. You should always use unsigned datatypes for bit fields.
• 09-12-2005
dwks
Quote:

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).
• 09-12-2005
loko
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```
• 09-12-2005
dwks
That's because it isn't unsigned!
• 09-12-2005
loko
Quote:

Originally Posted by dwks
That's because it isn't unsigned!

Works fine now :) Whats the difference in using unsigned char and char?
• 09-12-2005
Hammer
The good book says:
Quote:

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.
• 09-12-2005
dwks
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.
• 09-13-2005
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
• 09-13-2005
loko
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 :)