I have a very simple code, in which logical shift works with ~0 value in strange way
As I know its related to the signed/unsigned data types
#include <stdio.h>
void printfbits(int x) {
for (int i=7; i>=0;i--) {
printf("%d", x>>i & 1);
}
printf("\n");
}
int main() {
printfbits(~0>>1);
}
I expect 0111111, not 1111111. I also tried, no success
printfbits(((unsigned int)~0)>>1);
On most platforms, int
is 32 bits or 64 bits long. Therefore, you are shifting more than 8 bits to the right, which leaves you with more than 8 bits enabled:
11...11111111 >> 1
becomes:
11...11111111 // if sign extension happens
01...11111111 // if not
As you see, regardless of whether sign extension happens or not, you will still see all 1
s since you only print the lower 8 bits.
Right shift of negative signed values is implementation defined . For gcc, a 1 is shifted in, otherwise a 0 is shifted in.
You were on the right track with the cast, but it doesn't help since the function still expects an int
. You need to change the function to take an unsigned char
and you have to mask out all but the lowest byte before performing the shift in the function call.
#include <stdio.h>
void printfbits(unsigned char x) {
for (int i=7; i>=0;i--) {
printf("%d", x>>i & 1);
}
printf("\n");
}
int main() {
printfbits((~0u & 0xff)>>1);
}
Also, note the use of the U
suffix on the constant 0. That gives the constant a type of unsigned int
.
The negation in ~0
will happen with type int
. But even if you do ~(unsigned char)0
, it'll still happen with type int because of implicit promotions. Consequently, you'll get extra more 1-bits on the left (int is usually 32 bits large (must be at least 16)). You can strip them by casting the bitnegation result to uint8_t
.
I'd also recommend doing bit ops on unsigned
s ( 0
u rather than 0
) as the semantics are better standardized for those.
#include <stdio.h>
#include <stdint.h>
void printfbits(int x) {
for (int i=7; i>=0;i--) {
printf("%d", x>>i & 1);
}
printf("\n");
}
int main() {
printfbits( (uint8_t)~0u >>1 ); //prints 01111111
}
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.