简体   繁体   中英

I can't understand why I get this result when I bitwise OR a short and char

Could someone please explain why I get this result when I bitwise OR two numbers? I'm really confused.

signed char signedChar = -64;       // This is now -64, or 1100 0000
unsigned char unsignedChar = signedChar; // This is now 196, or 1100 0000 (The same)

short signedShort = 0;     // This is now 0000 0000 0000 0000
signedShort |= signedChar;   // This is now -64, not 196 

What I expected to happen was this, I or'ed signedShort and signedChar, which is:

0000 0000 0000 0000 or'ed with
          1100 0000
0000 0000 1100 0000 result 
equalling 196.

But instead I got -64

Why does this OR operation add a one at the beginning? I totally expected something different.

Thanks.

The expression signedShort |= signedChar; is interpreted as

signedShort = signedShort | signedChar;

Both operands of the | operator are promoted to int , the bitwise or operation is performed on these promoted values and the resulted is converted to the type of the destination, short .

Hence the value of signedChar , -64 is extended as an int with the same value. Or-ing to 0 does not change the value. Converting it to short also keeps the value because -64 is within the range of short , so the result is -64 .

Note that this does not depend on the actual representation of integers. You assume 2s complement in your question, but it would produce the same result with sign+magnitude or 1s complement.

Signed types with negative values will be extended with ones. An unsigned type will be extended with zeros.

Your unsigned char gets promoted to signed, since that is what you are performing operations with.

Signed is a promotion from unsigned

In your example:

0000 0000 0000 0000 or'ed with
1111 1111 1100 0000
1111 1111 1100 0000 result

That is how basically Two's complement arithmetic works. To preserve sign of a value, a special operation Sign extension is applied during conversion.

Let's take a simpler example of -10:

signed char signedChar = -10; // bits: 11110110b
signed short signedShort = signedChar; // bits: 1111111111110110b

Why not 1000000000000110b as you seem expected it to be? Because 1000000000000110b is -32762 in two's complement :-(

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM