0
#include <iostream>
#include <string>
#include <bitset>

int main()
{
    char c = 128;
    unsigned int shift2 = (unsigned int)c;
    std::string shift2bin = std::bitset<8>(shift2).to_string(); //to binary
    std::cout << " shift2bin: " << shift2bin << std::endl;

    unsigned int shift3 = shift2 >> 1;
    std::string shift3bin = std::bitset<8>(shift3).to_string(); //to binary
    std::cout << " shift3bin: " << shift3bin << std::endl;

}

Output:

 shift2bin: 10000000
 shift3bin: 11000000

I expect the result to be as follows:

 shift2bin: 10000000
 shift3bin: 01000000

Question> Why unsigned int right shift uses 1 as the filler?

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
q0987
  • 34,938
  • 69
  • 242
  • 387
  • 1
    If `char` on your system is a signed 8-bit type, which is not uncommon, then assigning 128 to `c` is probably not what you want ("implementation-defined behavior", I think). At present you're only printing the low 8 bits of `shift2`. Try printing out the rest of the bits of `shift2` for more insight into what is going on. – Nate Eldredge Apr 27 '16 at 00:46
  • 2
    It uses 0 as the filler. `shift2` in binary is `11111111111111111111111110000000`. You are only outputting the last 8 digits; the fill digit doesn't matter. – M.M Apr 27 '16 at 00:46
  • 1
    The answer, of course, is that unsigned right shift doesn't use 1 as the filler. But since `unsigned` is likely more than 8 bits, you're not looking at the filler bit that was shifted in; you're seeing that `shift2` had a 1 in bit 9. Likely because `c` is a signed type and got assigned a negative value. – Nate Eldredge Apr 27 '16 at 00:47
  • use `32` instead of `8` in bitset (or whatever width of int is on your machine) to see the full story – M.M Apr 27 '16 at 00:48
  • change the `char` to 'unsigned char` fixed my issues. – q0987 Apr 27 '16 at 00:48

1 Answers1

3

As seen in this answer, unsigned right shifts always zero-fill. However, try this to print out all the bits in the unsigned int:

std::string shift2bin = std::bitset<sizeof(shift2)*8>(shift2).to_string(); //to binary
std::cout << " shift2bin: " << shift2bin << std::endl;

You will see something like (as you appear to have char signed by default):

shift2bin: 11111111111111111111111110000000
                                   ^^^^^^^^

If you do the same for shift3bin, you will see:

shift3bin: 01111111111111111111111111000000
                                   ^^^^^^^^

So, you can see how you appear to get a "1" fill.

Community
  • 1
  • 1
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114