Type conversion: signed int to unsigned long in C

c, kernighan-and-ritchie, type-conversion

Solution

Whatever data-type you choose, `~077` will set the rightmost 6 bits to `0` and all others to `1`.

Assuming 16-bit `int`s and 32-bit `long`s, there are 4 cases:

Case 1

unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000

Case 2

unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000

Case 3

int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000

Case 4

int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000

See code here. This means the sign extension is done when the source is `signed`. When the source is `unsigned`, sign bit is not extended and the left bits are set to `0`.

Problem

I'm currently up to chapter 2 in The C Programming Language (K&R) and reading about bitwise operations. This is the example that sparked my curiosity: ``` x = x & ~077 ``` Assuming a 16-bit word length and 32-bit long type, what I think would happen is 077 would first be converted to: ``` 0000 0000 0011 1111 (16 bit signed int). ``` This would then be complemented to: ``` 1111 1111 1100 0000. ``` My question is what would happen next for the different possible types of x? If x is a signed int the answer is trivial. But, if x is a signed long I'm assuming ~077 would become: ``` 1111 1111 1111 1111 1111 1111 1100 0000 ``` following 2s complement to preserve the sign. Is this correct? Also, if x is an unsigned long will ~077 become: ``` 0000 0000 0000 0000 1111 1111 1100 0000 ``` Or, will ~077 be converted to a signed long first: ``` 1111 1111 1111 1111 1111 1111 1100 0000 ``` ...after which it is converted to an unsigned long (no change to bits)? Any help would help me clarify whether or not this operation will always set only the last 6 bits to zero.

Original source