levon
levon

Reputation: 19

How to explain the bit right shift two different results?

I get two different results, I'm confused, the code is :

int main () 
{
    int i = 0xcffffff3;
    printf("%x\n", 0xcffffff3>>2);
    printf("%x\n", i>>2);

    return 0;
}

the result is :

33fffffc
f3fffffc

Upvotes: 0

Views: 98

Answers (2)

It all comes down to 0xcffffff3. That is an hexadecimal integer constant. The type of the constant depends on its magnitude. Let's refer to C11 § 6.4.4.1 ¶ 5:

The type of an integer constant is the first of the corresponding list in which its value can be represented.

Octal or Hexadecimal Constant - int, unsigned int, long int, unsigned long int, long long int, unsigned long long int

So assuming 32 bit integer representation on your system. The type of 0xcffffff3 is unsigned int.

Now, when you do int i = 0xcffffff3; the unsigned constant is converted to a signed integer. This conversion yields a negative value.

Finally, when right shifting, it has the semantics defined by C11 §6.5.7 ¶5:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

Shifting the unsigned constant yields 0xcffffff3/4 and shifting i yields an implementation defined value (a negative integer in this case).

Upvotes: 4

grek40
grek40

Reputation: 13438

In 0xcffffff3 >> 2, both values are treated as unsigned while in i >> 2, i is signed.

As a result, the arithmetic shift is prepending 1 bits in the signed case because the number is negative before shifting.

Use (unsigned)i >> 2 or define unsigned i = 0xcffffff3; if you want the same result as with the constants.

Upvotes: 3

Related Questions