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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With