How to explain this,what happens when we cast signed char to int/hex?
signed char num = 220; //DC in hex
printf("%02X\n", num);
printf("%d\n", num);
I know that sig开发者_StackOverflowned char
can only represent -128~127
,but why the above outputs:
FFFFFFDC
-36
What's the reason?
UPDATE
My above code is just contrived for my question,that is ,what happens when we cast signed char to int/hex
As our starting point, 220 = DC in hex, and 11011100 in binary.
The first bit is the sign-bit, leaving us with 1011100. Per two's complement, if we complement it (getting 0100011), and then add one, we get 0100100 -- this is 36.
When it converts the signed char to signed int, it doesn't say "this would be 220 if it's unsigned", it says "this is -36, make it an int of -36", for which the 32-bit two's complement representation is FFFFFFDC, because it must be the negative value for the full size of int (this is called sign-extension):
+36 as a 32-bit value: 00000000000000000000000000100100
complement: 11111111111111111111111111011011
add one: 11111111111111111111111111011100
Or, in hex, FFFFFFDC
.
This is why you must be careful with printf("%x", ch);
(and relatives) -- if you intend to just get a two-digit value, and chars are signed, you may wind up with eight digits instead. Always specify "unsigned char" if you need it to be unsigned.
As you pointed out, the signed car can have a max value of 127. The reason for the negative number there, however, is due to how the char is stored in memory. All signed integer types save the final bit for sign, with 0/1 denoting positive/negative. The compiler, however, does not check overflow, so when you tried to assign num to 220, it overflowed the value into the sign bit since it could not fit it into the first 7 bits of the char (chars are 1 byte). As a result, when you try to read what is in memory, it sees the sign bit as thrown making the compiler think that instead of seeing a large positive number as you intended, it is instead seeing a small negative value. Hence, the output you see.
Edit Responding to your updated question. All that happens is that the compiler will copy or expand the char to have 4 bytes of memory, interpret the value of the char, and rewrite it in the new int's memory. In you're case, the program at run time would think that the char has a value of -36 instead of 220 because it's interpreting those bits as a signed char before the cast. Then, when it casts, it simply creates an int with value -36.
Your overflow on the assignment, combined with sign extension when you promote it to an int to view it in hex ... see What's happening in the background of a unsigned char to integer type cast?
Any type smaller that "int" gets converted to "int" when it's passed via "...". This means your negative char got converted to negative int, with FFFs showing up in hex printout.
精彩评论