I'm attempting to implement circular bit-shifting in C++. It kind of works, except after a certain point I get a bunch of zeroes.
for (int n=0;n<12;n++) {
unsigned char x=0x0f;
x=((x<<n)|(x>>(8-n))); //chars are 8 bits
cout<<hex<<"0x"<<(int)x<<endl;
}
My output is:
0xf
0x1e
0x3c
0x78
0xf0
0xe1
0xc3
0x87
0xf
0x0
0x0
0x0
As you can see, I start getting 0x0's instead of the expected 0x1e, 0x3c, etc.
If I expand the for loop to iterate 60 times or so, the numbers come back correctly (after a bunch of zeroes.)
I'm assuming that a char houses a big space, and the "gaps" of unused data are zeroes. My understanding is a bit limited, so any suggestions would be appreciated. Is there a way to toss out those zeroes?
Shifting by a negative amount is undefined behavior.
You loop from 0
to 12
, but you have an 8 - n
in your shifts. So that will go negative.
If you want to handle n > 8
, you'll need to take a modulus by 8. (assuming you want 8-bit circular shift.)
for (int n=0; n < 12; n++) {
unsigned char x = 0x0f;
int shift = n % 8; // Wrap modulus
x = ((x << shift) | (x >> (8 - shift))); //chars are 8 bits
cout << hex << "0x" << (int)x << endl;
}
Shifting a byte left by more than 7 will always result in 0. Also, shifting by a negative amount is not defined.
In order to fix this you have to limit the shift to the size of the type.
Basically:
unsigned char x = 0xf;
int shift = n&7;
x=((x<<shift)|(x>>(8-shift)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.