0

Why does right shift have two choices — appending the sign bit (arithmetic right shift) or appending 0 (logical right shift) and why does the implementation get to choose which?

phuclv
  • 37,963
  • 15
  • 156
  • 475
CHID
  • 1,625
  • 4
  • 24
  • 43
  • yeah. I am able to get that. So why does appending sign bit come into picture for right shift? – CHID Jun 07 '13 at 05:33
  • Left shifting is already arithmetic; it's the same as multiplying by a power of two. Filling in the least-significant-bits with sign-bits makes no sense. – jamesdlin Jun 07 '13 at 05:34
  • True. Please help me understand the same for right shift – CHID Jun 07 '13 at 05:35
  • 1
    Why people downvoting the question? please add comment? I think its an obvious question. Is it duplicate from somewhere? – Grijesh Chauhan Jun 07 '13 at 06:06
  • 1
    Why is this tagged 'C'? You don't have that choice, in C. Java has [`>>` and `>>>`](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html) that allows you to differentiate between the two kinds of shift, but C does not. – unwind Jun 07 '13 at 06:09

5 Answers5

4

The difference is to allow the handling of both signed (two's complement) and unsigned integers.

  • When right-shifting a signed (two's complement) integer the most-significant bit is the sign; 0 for positive or zero, and 1 for negative. In order to retain the sign on the right-shift, one must duplicate the existing high-order bit, or appending the sign as you prefer .

  • When right-shifting an unsigned integer, in order to retain the magnitude properly one must append zero on the left regardless of the existing high-order bit.

Pieter Geerkens
  • 11,775
  • 2
  • 32
  • 52
3

if you want to shift the sign bit as well, i believe you are looking for a circular left shift operation and not a "standard left shift" operation.

you could look at the question posed on the following link: Circular shift in c

For a better understanding of bitwie operations you could look at the following wikipedia page https://en.wikipedia.org/wiki/Bitwise_operation

Community
  • 1
  • 1
Sigurd V
  • 5,077
  • 4
  • 18
  • 27
  • 1
    +1 for mentioning circular shift. -1 for 'right shift should not be implementation dependent'. It is implementation dependent for (negative) signed values. – Jonathan Leffler Jun 07 '13 at 05:41
  • Hi Jonathan. Deleted my statement about the shift not being implementation dependent. Didn't consider negative values when i wrote it. Thanks – Sigurd V Jun 08 '13 at 02:59
2

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.

I guess you are referring to this paragraph.

This is because the standard does not define how a negative number will be stored (2's complement, 1's complement, etc.) - it is implementation defined (hardware dependent).

It is "almost" the same for left shift on signed integers.

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

phuclv
  • 37,963
  • 15
  • 156
  • 475
joy
  • 1,569
  • 8
  • 11
1

Your question is nonsensical. In a two's complement system, the sign of a number is determined by its highest order bit. For a right shift, you can either decide to shift in a zero (logical shift) or a copy of the sign bit (arithmetic shift). For a left shift, the only meaningful operation is to shift in zero.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • Hi Carl. Thanks! Now `For a right shift, you can either decide to shift in a zero (logical shift) or a copy of the sign bit (arithmetic shift)`. In what case the either of them changes? – CHID Jun 07 '13 at 05:36
  • 1
    I don't understand your question. – Carl Norum Jun 07 '13 at 05:37
  • I mean, you say, in a right shift we either decide to shift a zero, or copy the sign bit. Why is that?? – CHID Jun 07 '13 at 05:38
  • @CHID: Because when right-shifting, there's a choice between doing an arithmetic right-shift or a logical right-shift. Implementations get to choose. If they choose arithmetic, they must preserve the sign bit and do sign-extension (so `-64 >> 1` produces -32). When left-shifting, there is no such choice. – jamesdlin Jun 07 '13 at 05:40
  • @jamesdlin Still that `if` clause baffles me. So I will put the question like this. When do they choose arithmetic and when do they choose logical? – CHID Jun 07 '13 at 05:48
  • Usually they choose depending on the underlying instruction set they're writing the compiler for. It's really just a design choice though. – Carl Norum Jun 07 '13 at 05:51
  • 1
    @CHID: It's an arbitrary choice. They could flip a coin for all you care. If you want arithmetic right-shift, just use `/`. If you want logical right-shift, you probably shouldn't be using signed integer types in the first place. – jamesdlin Jun 07 '13 at 05:53
0

Under a twos complement representation, a "normal" left-shift acts exactly like an arithmetic left-shift: left-shifting a negative number results in that number being doubled (as long as the result does not overflow).

caf
  • 233,326
  • 40
  • 323
  • 462