user3116473 - 6 months ago 32

C Question

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);

Answer

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:

2The 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 theinteger 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`

).