简体   繁体   中英

Can't understand C program output

I was making some basic programs and i made this program

 #include<stdio.>
 int main()
 {
   printf("%d\n",-1>>4);
   return 0;
 }

output = -1

i could not understand how it happens ?

is -1 is 2's complemented first and then shift operation is done .and then again 2's complement is done to produce the result.

i also want to know how this output comes

int main()
{
 unsigned int a=4;
 printf("%d\n",-a>>4);
 return 0;   
}

result = 268435455

For a start, what you're doing is non-portable.

ISO C11 states, in 6.5.7 Bitwise shift operators :

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 / 2^E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

So it's not wise to do that.

What's possibly happening is that you have an implementation that preserves sign on the negative values. Whereas >> may normally shift in zero bits on the left hand side (and must do so for an unsigned or signed-nonnegative value), your implementation could detect a negative number and shifts in one-bits into the second-from-left position, leaving the left bit untouched.

That means -1 (eg: binary 1111 1111 1111 1111 ) will still have that bit pattern after a right-shift.

You would have to examine the documentation for your particular implementation to be sure (Appendix J of the standard requires implementations to document their choices for implementation-defined behaviours).

You could also test it with a few better sample values like binary 1100 0000 0000 0000 right-shifted by one bit, and see what comes out (though, of course, the implementation notes should be the definitive source).


By way of example, the gcc documentation provides this information here . Since you mention you're using 4.6.3, the 4.6.4 manuals are probably the closest.

The GCC 4.6.4 Manual (also in PDF or PostScript or an HTML tarball) link on that page contains a section entitled C implementation-defined behaviour which states, in part:

The results of some bitwise operations on signed integers (C90 6.3, C99 6.5).

Bitwise operators act on the representation of the value including both the sign and value bits, where the sign bit is considered immediately above the highest-value value bit. Signed '>>' acts on negative numbers by sign extension.

That means it acts as I explained, with the left bit staying put and affecting the second-most left bit:

在此处输入图片说明


The reason why you're seeing a different value with:

unsigned int a=4;
printf("%d\n",-a>>4);

is because -a is, for some reason I'm not entirely certain of, being treated as the unsigned representation of -4. You can see that with:

#include <stdio.h>
int main()
{
    unsigned int a=4;
    printf("%09x\n",((unsigned int)(-a))>>1);
    printf("%09x\n",(-a)>>1);
    printf("%09x\n",(-((int)a))>>1);
    return 0;
}

which outputs (annotated):

07ffffffe  # explicit unsigned int
07ffffffe  # seemingly treated as unsigned int

0fffffffe  # explicit int

I suspect this has to do with integer promotions and the usual arithmetic conversions detailed in ISO C11 6.5 Expressions but I think that's moving well beyond the scope of the original question.

-1 has the binary representation (assuming 2's complement):

11111111111111111111111111111111       // All ones, 32 of them if we assume 32 bit ints

When right-shifting signed numbers, your compiler seems to shift in 1 if the sign bit is 1.

11111111111111111111111111111111       // All ones, 32 of them if we assume 32 bit ints
^^^^ These 4 are new

As you can see, the number stays the same, -1.

-1是FFFFFFFF,按位,因此当您右移任何位时,它仍将是FFFFFFFF,即-1

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