abacus
abacus

Reputation: 43

different result about bitwise operator in C

in order to realize logical right shift in c , i search the web and got the following C code

int a, b, c;
int x = -100;
a = (unsigned) x >> 2;
b = (0xffffffff & x) >> 2;
c = (0x0 | x ) >> 2;

now both a and b were logical right shift result(1006632960), but c was still arithmetic shift result(-25), could somebody explain why ? thx

Upvotes: 1

Views: 362

Answers (3)

valdo
valdo

Reputation: 12943

It's all about the operand type of the operator >>. If it's signed - the right-shift sets the MSB to 1 if the operand was negative. If the operand is unsigned - MSB bits are always zero after right-shift.

In your first expression the operand is cast explicitly to unsigned.

In the second expression the (0xffffffff & x) us unsigned, because 0xffffffff definitely represents an unsigned integer (it's an overflow for signed).

OTOH in the third example 0x0 is signed (this is the default for integer constants). Hence the whole operand (0x0 | x ) is considered signed

Upvotes: 0

AProgrammer
AProgrammer

Reputation: 52284

(unsigned) x is of type unsigned int so it get a logical shift.

0xffffffff (assuming 32 bit int) is of type unsigned int, so (0xffffffff & x) is also of type unsigned int so it get a logical shift.

0x0 is of type int, so (0x0|x) is of type int and get an arithmetic shift (well, it is implementation dependent).

Upvotes: 1

hmakholm left over Monica
hmakholm left over Monica

Reputation: 23332

b = (0xffffffff & x) >> 2;

Assuming that your ints are 32 bits, the type of the literal constant 0xffffffff is unsigned int, because it is too large to fit in a plain int. The &, then, is between an unsigned int and an int, in which case the unsigned type wins by definition. The shift therefore happens on unsigned; thus it shifts in 0 bits from the left.

c = (0x0 | x ) >> 2;

The type of 0x0 defaults to int because it is small enough to fit, so the bitwise or happens on ints, and so does the following shift. It is implementation defined what happens when you shift a signed integer right, but most compilers will produce an arithmetic shift that sign-extends.

Upvotes: 1

Related Questions