Reputation: 595
#include <stdio.h>
int main(int argc, char const *argv[])
{
char a = 0xAA;
int b;
b = (int)a;
b = b >> 4;
printf("%x\n", b);
return 0;
}
Here the output is fffffffa
. Could anyone please explain to me how this output was obtained?
Upvotes: 3
Views: 4698
Reputation: 726809
C standard allows compiler designers choose if char
is signed or unsigned. It appears that your system uses signed char
s and 32-bit int
s. Since the most significant bit of 0xAA
(binary 10101010
) is set, the value gets sign-extended into 0xFFFFFFAA
.
Shifting signed values right also sign-extends the result, so when you shift out the lower four bits, four ones get shifted in from the left, resulting in the final output of 0xFFFFFFFA
.
EDIT : According to C99 specification, hexadecimal integer constants such as 0xAA
in your example are treated as int
s of different length depending on their length. Therefore, assigning 0xAA
to a signed char
is out of range: a proper way of assigning the value would be with a hexadecimal character literal, like this:
char a='\xAA';
Upvotes: 3
Reputation: 158539
The standard allows char
to be either signed
or unsigned
in your case it looks like it is signed
. Assigning 0xAA
to a signed char
is signed overflow and therefore undefined behavior. So if you change your declaration to this:
unsigned char a=0xAA;
you should get the results you expect.
Upvotes: 2
Reputation: 3034
It looks like 0xAA got sign extended when you put it into an int to 0xFFFFFFAA. Then, when you right-shifted it by four bits (one hex character) you ended up with 0xFFFFFFFA.
//a is 8-bits wide. If you interpret this as a signed value, it's negative
char a=0xAA;
int b; //b is 32 bits wide here, also signed
//the compiler sign-extends A to 0xFFFFFFAA to keep the value negative
b=(int)a;
b=b>>4; //right-shift maintains the sign-bit, so now you have 0xFFFFFFFA
Upvotes: 2