简体   繁体   中英

Left shift operator in C

Consider:

#include <stdio.h>
#define macro(a) a=a<<4;

main()
{
    int a = 0x59;
    printf("%x", a);
    printf("\n");
    macro(a)
    printf("%x", a);
}

For the above code, I am getting the below output:

59
590

Why am I not getting the below output as the left shift operation?

59
90

Left shifts does NOT truncate the number to fit the length of the original one. To get 90 , use:

(a<<4) & 0xff

0x59 is an int and probably on your platform it has sizeof(int)==4 . Then it's a 0x00000059 . Left shifting it by 4 gives 0x00000590 .

Also, form a good habit of using unsigned int types when dealing with bitwise operators, unless you know what you are doing. They have different behaviours in situations like a right shift.

You shifted a hexadecimal number by 4 places to left so you get 590, which is correct.

you had

000001011001    

shifted to left by 4 bits

010110010000

is 590 in hex

10010000

is 90 in hex so you might want to remove 0101 as is shown by phoeagon

In your printf if you change %x to %d you get a =89 and after left shifting you will get a = 1424

Generally for decimal (base 10) numbers

a = a<< n  is  a = a*2^n
a = a>> n  is  a = a/2^n

For Hexadecimal (base 16) numbers ,

Any shift by n (left or right) , can be considered , as a corresponding shift of the digits of the binary equivalent. But this depends on sizeof(int) , used for a given compiler.

You are using int so you have :

 000001011001  

If you shift it by 4 to the left you get :

010110010000

If you only want to have only the first 8 bits you don't have to use "int" but unsigned char (or char)

#include<stdio.h>
#define macro(a) a=a<<4;
main()
{
   unsigned char a=0x59;
   printf("%x",a);
   printf("\n");
   macro(a)
   printf("%x",a);            
}

if you still want to use int but only keep the first 8 bits you can use a mask :

#define macro(a) a=(a<<4) & 0xFF

So could you please tell me what should I do so as to get the output as 0x90? I need to shift the last 4 bits to the first 4 bits adding 0's at the end

The only way you can shift the 4 last bit 4 bit to the left AND get it in the place of the first 4 bit is if your type have just 8 bit. Usually this is the case of unsigned char , not int . You will get 0x90 for

unsigned char a=0x59;
macro(a)

but when using int the result is 0x590 The error is not with the use of the << is with the selection of the type. (or a misuse of macro?)

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