Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why ~0 >> 1 doesn't shift the bit?

I just learn from K&R c book chapter 2, let's say i have this code:

#include <stdio.h>
int
main(void)
{
    printf("0x%016llx\n", ~0); //0x00000000ffffffff

    printf("0x%016llx\n", ~0 >> 1); //0x00000000ffffffff
    printf("0x%016llx\n", 0x00000000ffffffff >> 1); //0x000000007fffffff
    return 0;
}

I expect ~0 >> 1 will give 0x000000007fffffff like how 0x00000000ffffffff >> 1 do, which ~0 has the value of 0x00000000ffffffff.

Why ~0 >> 1 doesn't shift the bit ?

like image 418
林果皞 Avatar asked Feb 06 '23 14:02

林果皞


1 Answers

The llx format specifier expects an unsigned long long argument, but you're passing in an int.

The shift is not giving you what you expect because ~0 results in an int with a negative value. So doing a right shift preserves the sign bit, i.e. a 1 bit is shifted in to the left.

Put the ULL suffix on your integer constants to force them to be the proper type:

printf("0x%016llx\n", ~0ULL);
printf("0x%016llx\n", ~0ULL >> 1);
printf("0x%016llx\n", 0x00000000ffffffffULL >> 1);

Then you'll get the expected output:

0xffffffffffffffff
0x7fffffffffffffff
0x000000007fffffff

Because the values are now unsigned, a 0 bit always gets shifted into the left.

like image 156
dbush Avatar answered Feb 08 '23 04:02

dbush