~'q' << 6

'q' is 113 in int, and 01110001. ~'q' is then 10001110, and since it's promoted to int, it's 11111111 11111111 11111111 10001110. And finally it's shifted to left by 6, so it's 11111111 11111111 11100011 10000000.

cout << (int) 'q' << " " << ~'q' << " " << (~'q' << 6) << endl;

when I printed it, the output is

113 -114 -7296

my question is ~'q' should be promoted to int, and shouldn't the output be int and not signed char, which is represented by -114 in two's complement?

and for (~'q' << 6), I guess I am a bit rusty on how integer is represented, why is the value -7296?

11111111 11111111 11111111 10001110 is the 32-bit representation of -114.

just like '10001110' is the 8-bit representation of -114.

and for (~'q' << 6), I guess I am a bit rusty on how integer is represented, why is the value -7296?

(~'q' << 6) is:

11111111 11111111 11100011 10000000, which is the 32-bit representation of -7296.

Each bit has a weight of 2n where 'n' is the bit index (bit 0 being the lowest bit, and bit 31 being the highest bit). You sum all the weights of the bits that are set (1), and that gets you the result.

With signed numbers, the high bit has a negative weight, which means its weight is actually -(2n).

since 11111111 11111111 11111111 10001110 is -114, that mean compiler knows it's a char and thus interpret that way instead of interpreting it as an int? and 000...000 10001110 is as well interpreted as char?