10

In this code below

int main()
{
int  a = -1;
printf("%d",a>>1);
return 0;
}

Why it is giving output -1.

algo-geeks
  • 5,280
  • 10
  • 42
  • 54
  • 1
    See this question [shift operator in C](http://stackoverflow.com/questions/7622/shift-operator-in-c). – Mat Mar 29 '11 at 18:09

6 Answers6

12

bit-shifting is defined only on unsigned types, for signed types it is implementation-defined. And this is a useful refinement by R..

Strictly speaking, it is defined for signed types whenever the value is positive and the result does not overflow, and right shift is implementation-defined for negative values. Left shift, on the other hand, is undefined for negative values

┌───┬──────────────┬──────────────────────────────────┬────────────────────────┐
│   │ Unsigned     │ Signed, positive                 │ Signed, negative       │
├───┼──────────────┼──────────────────────────────────┼────────────────────────┤
│<< │ well-defined │ well-defined, except on overflow │ undefined behaviour    │
│>> │ well-defined │ well-defined                     │ implementation-defined │
└───┴──────────────┴──────────────────────────────────┴────────────────────────┘
caf
  • 233,326
  • 40
  • 323
  • 462
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 4
    Strictly speaking, it is defined for signed types whenever the value is positive and the result does not overflow, and right shift is implementation-defined for negative values. Left shift, on the other hand, is *undefined* for negative values. – R.. GitHub STOP HELPING ICE Mar 29 '11 at 18:07
  • 1
    I believe that would be "implementation-defined" in C99 according to [Wikipedia: Arithmetic shift](http://en.wikipedia.org/wiki/Arithmetic_shift) – Mat Mar 29 '11 at 18:11
5

Because -1 is 1111111...111 in binary. a>>1 operation will "sign extend" the sign bit, so you get 1111111...111 again.

Joel Lee
  • 3,656
  • 1
  • 18
  • 21
  • This is only in complementary code, which isn't necessarily the way numbers are represented. But still, on many platforms you are right – Armen Tsirunyan Mar 29 '11 at 18:11
  • @Arment - Agreed, it is definitely machine dependent. I should have pointed that out. Clearly, though, sign extend is what is happening in this particular case. – Joel Lee Mar 29 '11 at 18:12
  • @Armen - Don't know if you got previous comment. (Sorry, typo on your name.) – Joel Lee Mar 29 '11 at 18:21
1

Most compilers choose to interpret >> on signed numbers to be arithmetic shift. Thus since the number is initially negative (i.e. the MSB bit is 1), after a right shift, that bit is replaced by another 1 to preserve the sign, ergo you end up with -1 as you started.

michel-slm
  • 9,438
  • 3
  • 32
  • 31
0

In Memory signed integer number stored as 2's complement if sign int and when data is read from memory {%d} it's converted into original form so here 2's complement of -1 will stored in memory let say integer take 2 byte so 2's complement of -1 is 1111 1111 1111 1111

After perform a>>1 It will change 0111 1111 1111 1111 now As we know that when data is read from memory it's again converted to 0 complement so take 2's complement of 0111 1111 1111 1111 It will be like 1000 0000 0000 0001 which is equal to -1

Note: 2's complement of +ve number is same as original binary representation 2's complement is only for -ve number. In C number always stored as 2's complement form

Nishant Kumar
  • 5,995
  • 19
  • 69
  • 95
  • 2
    First, unsigned numbers are not stored as 2's complement. For signed numbers, not all architectures/compiler implementations use 2's complement too. C standard allows for any other number encoding although it's almost impossible to find a 1's complement or sign-magnitude implementation nowadays – phuclv Dec 26 '13 at 06:06
  • @LưuVĩnhPhúc : why it's output coming -1 if unsigned is not stored as 2's complement #include void main() { unsigned int a = -1; printf("%d", a); } – Nishant Kumar Dec 26 '13 at 06:17
  • 1
    unsigned numbers are printed by `%u`, you're getting an undefined behavior – phuclv Dec 26 '13 at 06:20
  • 1
    try printing -1 on computers that use 1's complement or sign-magnitude and see – phuclv Dec 26 '13 at 06:21
0

The >> operator on a signed value may perform an arithmetic or logical shift, depending on the compiler. Arithmetic shifts retain the sign bit, so -1 (which on a 2-s complement machine, which these days is pretty much the only variety you will encounter) will remain -1 when right-shifted. (Note that the C standard explicitly does not specify whether >> on a signed number is an arithmetic or logical shift. It is always a logical shift on unsigned numbers, though.)

geekosaur
  • 59,309
  • 11
  • 123
  • 114
0

The definition of bit-shifting on signed values is implementation-dependent. Check your compiler's docs for how it handles it.

Unsigned
  • 9,640
  • 4
  • 43
  • 72