user3116473 - 1 month ago 6
C Question

# Confusion in the Bitwise operation

I just started to learn c language. I have a question about the result of bitwise operations. In the following code, why we get a different result from c and d? How do we have 72 as the value of d?

``````char a = 41;//101001
char b = (a<<5);//32 or 100000
char c = (b>>2);//8 or 1000
char d = (a<<5)>>2;//72 or 1001000
printf("a= %d , b=%d, b=%d , d=%d\n", a, b,c,d);
``````

When any type or arithmetic operation is performed on a type smaller than `int`, the value is promoted to `int` within the expression. Then when the result is saved to a `char`, all but the lowest order byte are truncated.

This covered in section 6.3.1.1 of the C standard:

2 The following may be used in an expression wherever an `int` or `unsigned int` may be used:

— An object or expression with an integer type (other than `int` or `unsigned int`) whose integer conversion rank is less than or equal to the rank of `int` and `unsigned int`.

— A bit-field of type `_Bool`, `int`, `signed int`, or `unsigned int`.

If an `int` can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an `int`; otherwise, it is converted to an `unsigned int`. These are called the integer promotions. All other types are unchanged by the integer promotions.

In the case of `c`, you first do `a<<5`. Before this happens, the value of `a` in this expression is promoted in `int`, so the result can be larger than a `char`.

This results in the binary value `10100100000` (decimal 1312). This is then saved to `b` which has type `char`, so only the lower 8 bits (`00100000`) are retained.

Then we perform `b>>2` giving us binary `00001000` (decimal 8) which is saved in `c`.

In the case of `d`, we perform `a<<5` as before (with the value of `a` being promoted to `int`) getting binary `10100100000`. Now this value is shifted right by 2 resulting in `00101001000` (decimal 328). This is then saved to `d` which is of type `char`, so only the lower 8 bits are saved (`01001000`).

Source (Stackoverflow)