# Arithmetic shift: Wikis

Note: Many of our articles have direct quotes from sources you can cite, within the Wikipedia article! This article doesn't yet, but we're working on it! See more info or our list of citable articles.

# Encyclopedia

Updated live from Wikipedia, last check: June 19, 2013 21:30 UTC (36 seconds ago)

A left arithmetic shift of a binary number by 1. The empty position in the least significant bit is filled with a zero. (Note that arithmetic left shift may cause an overflow - in this way it differs from logical left shift.) Note that the operation depicted is the same as that of the left logical shift.
A right arithmetic shift of a binary number by 1. The empty position in the most significant bit is filled with a copy of the original MSB.
Arithmetic shift operators in various programming languages
Language Left Right
VHDL sla[note 1] sra
Verilog <<< >>>[note 2]
C/C++[note 3], Java, JavaScript, Python, PHP, Ruby, etc. << >>
OpenVMS macro language @[note 4]
Scheme arithmetic-shift[note 5]
Common Lisp ash[note 5]
Ocaml lsl asr
Standard ML << ~>>

In computer programming, an arithmetic shift is a shift operator, sometimes known as a signed shift (though it is not restricted to signed operands). For binary numbers it is a bitwise operation that shifts all of the bits of its operand; every bit in the operand is simply moved a given number of bit positions, and the vacant bit-positions are filled in. Instead of being filled with all 0s, as in logical shift, when shifting to the right, the leftmost bit (usually the sign bit in signed integer representations) is replicated to fill in all the vacant positions (this is a kind of sign extension).

Arithmetic shifts can be useful as efficient ways of performing multiplication or division of signed integers by powers of two. Shifting left by n bits on a signed or unsigned binary number has the effect of multiplying it by 2n. Shifting right by n bits on a two's complement signed binary number has the effect of dividing it by 2n, but it always rounds down (towards negative infinity). This is different from the way rounding is usually done in signed integer division (which rounds towards 0). This discrepancy has led to bugs in more than one compiler.

For example, in the x86 instruction set, the SAR instruction (arithmetic right shift) divides a signed number by a power of two, rounding towards negative infinity.[1] However, the IDIV instruction (signed divide) divides a signed number, rounding towards zero. So a SAR instruction cannot be substituted for an IDIV by power of two instruction nor vice versa.

## History and details

The formal definition of an arithmetic shift, from Federal Standard 1037C is that it is:

A shift, applied to the representation of a number in a fixed radix numeration system and in a fixed-point representation system, and in which only the characters representing the fixed-point part of the number are moved. An arithmetic shift is usually equivalent to multiplying the number by a positive or a negative integral power of the radix, except for the effect of any rounding; compare the logical shift with the arithmetic shift, especially in the case of floating-point representation.

An important word in the FS 1073C definition is "usually". Arithmetic left shifts are equivalent to multiplication by a (positive, integral) power of the radix (e.g. a multiplication by a power of 2 for binary numbers). Arithmetic left shifts are, with one exception, identical in effect to logical left shifts. The exception is the minor trap that arithmetic shifts may trigger arithmetic overflow whereas logical shifts do not. However, arithmetic right shifts are major traps for the unwary.

It is frequently stated that arithmetic right shifts are equivalent to division by a (positive, integral) power of the radix (e.g. a division by a power of 2 for binary numbers), and hence that division by a power of the radix can be optimized by implementing it as an arithmetic right shift. (A shifter is much simpler than a divider. On most processors, shift instructions will execute more quickly than division instructions.) Steele quotes a large number of 1960s and 1970s programming handbooks, manuals, and other specifications from companies and institutions such as DEC, IBM, Data General, and ANSI that make such statements. However, as Steele points out, they are all wrong.

Arithmetic right shifts are only equivalent to division by a power of the radix on an "N-1's-complement" machine (for radix "N"). Arithmetic shifts of binary numbers are only equivalent to division by a power of 2 when the one's complement representation of signed numbers is being used, for example.

This description has been erroneously brought over from the older one's complement architectures to newer two's complement architectures. But with two's complement binary number representations, arithmetic right shift is not equivalent to division by a power of 2. For negative numbers, the equivalence breaks down. The most trivial example of this is the arithmetic right shift of the number -1 (which is represented as all ones) in a two's complement representation, which yields -1.

The (1999) ISO standard for the, C programming language defines the C language's right shift operator in terms of divisions by powers of 2. Because of the aforementioned non-equivalence, the standard explicitly excludes from that definition the right shifts of signed numbers that have negative values. It doesn't specify the behaviour of the right shift operator in such circumstances, but instead requires each individual C compiler to specify the behaviour of shifting negative values right.[note 6]

However, the aforementioned discrepancy arises only from the way division is defined on integers: On an "N's-complement" architecture (for radix "N") an arithmetic shift is equivalent to a division that rounds towards negative infinity, not towards zero. Donald Knuth describes this in terms of a floor function.

## Notes

1. ^ The VHDL arithmetic left shift operator is unusual. Instead of filling the LSB of the result with zero, it copies the original LSB into the new LSB. Whilst this is an exact mirror image of the arithmetic right shift, whereas the conventional definition of the operator is not, it is not the conventional definition of the operator, and is not equivalent to multiplication by a power of 2. In the VHDL 2008 standard this strange behavior was left unchanged (for backwards compatibility) for argument types that do not have forced numeric interpretation (e.g. BIT_VECTOR) but 'SLA' for unsigned and signed argument types behaves in the expected way (i.e. rightmost positions are filled with zeros). VHDL's SLL (Shift Left Logical) function does implement the aforementioned 'standard' arithmetic shift.
2. ^ The Verilog arithmetic right shift operator only actually performs an arithmetic shift if the first operand is signed. If the first operand is unsigned, the operator actually performs a logical right shift.
3. ^ The >> operator in C and C++ is not necessarily an arithmetic shift. The C99 standard specifies that the resulting value is implementation-defined for a right shift in which the left operand is a signed integer that is negative. However, most implementations use sign extension, thereby making the >> operator an arithmetic shift. For instance, the GCC is such an implementation (although if the left operand is unsigned, it will perform a logical shift).
4. ^ In the OpenVMS macro language whether an arithmetic shift is a left or a right shift is determined by whether the second operand is positive or negative. This is unusual. In most programming languages the two directions have distinct operators, with the operator specifying the direction, and the second operand is implicitly positive. (Some languages, such as Verilog, require that negative values be converted to unsigned positive values. Some languages, such as C and C++, do not have defined behaviours if negative values are used.)
5. ^ a b In Scheme arithmetic-shift can be both left and right shift, depending on the second operand, very similar to the OpenVMS macro language, although R6RS Scheme adds both -right and -left variants.
6. ^ The C standard was intended to not restrict the C language to either one's complement or two's complement architectures. In cases where the behaviours of one's complement and two's complement representations differ, such as this, the standard requires individual C compilers to document the actual behaviour of their target architectures.