2
votes

I understand that shifting means moving each bit to the left or right respectively,but when I try to shift 0x30 by 4 positions to the left I get 0x300 or 00110000000 in binary.(my desired output would be 0000 0000 ).Why does it behave this way? My code in C:

int main(void){
 unsigned int a;
 scanf("%x",&a);
 printf("%b",a<<4);
}

Input:30 Output:300 Expected output:0 Edit:I would expect this output if I use more than 1 byte for my assigned variable ,but unsigned int is exactly 1 byte and 0x300 is 12 bits.

2
I'm not sure where you get that unsigned int is exactly 1 byte. It isn't. It's at least 2 bytes and almost always 4. You can check with sizeof(unsigned int)Daniel H
int is 32-bit, not 8bit.svtag
"unsigned int is exactly 1 byte": that seems highly unlikely; your premise might be wrong here. What is your platform (OS, hardware) that you are running on? See also stackoverflow.com/questions/11438794/…9769953
If you want 1byte memory, better to use uint8_t or int8_t data type, it is defined in header stdint.h.svtag
@svtag not always, don't make that assumption.Qix - MONICA WAS MISTREATED

2 Answers

3
votes

a is an int which is (usually) 32 bits long.

The value of 0x300 is expected for an int.

Even if you use a uint8_t for a you need to typecast the result back to uint8_t to see the expected result.

int main(void){
  uint8_t a;
  scanf("%hhx",&a);  // you need hhx to read unsigned char (C99 only) 
  printf("%hhx",(uint8_t) (a<<4));
}

For your information, if you do not typecast, the value a<<4 will be promoted to int and 0x300 will be displayed

0
votes

0x30 is hex and 0000000000110000 in binary. If you shift 4 bits, you get your result 0x300 or 0000001100000000.

To respond to your edit, unsigned int does not take 1 byte. It takes the same number of bytes as an int does. Which in your case it is probably 4 bytes or 32 bits.

The reason the number is shown with 2 or 3 hex digits, its because the 0-s in the beginning are not printed. But the number is in fact 0030(hex) .

Anyway, you can check the size using sizeof.

EDIT: If you want to take 1 byte, see Rishikesh answer.