In
computer programming
Computer programming or coding is the composition of sequences of instructions, called computer program, programs, that computers can follow to perform tasks. It involves designing and implementing algorithms, step-by-step specifications of proc ...
, an arithmetic shift is a
shift operator, sometimes termed a signed shift (though it is not restricted to signed operands). The two basic types are the arithmetic left shift and the arithmetic right shift. For
binary number
A binary number is a number expressed in the Radix, base-2 numeral system or binary numeral system, a method for representing numbers that uses only two symbols for the natural numbers: typically "0" (zero) and "1" (one). A ''binary number'' may ...
s it is a
bitwise operation
In computer programming, a bitwise operation operates on a bit string, a bit array or a binary numeral (considered as a bit string) at the level of its individual bits. It is a fast and simple action, basic to the higher-level arithmetic operatio ...
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
In computer science, a logical shift is a bitwise operation that shifts all the bits of its operand. The two base variants are the logical left shift and the logical right shift. This is further modulated by the number of bit positions a given v ...
, 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).
Some authors prefer the terms ''sticky right-shift'' and ''zero-fill right-shift'' for arithmetic and logical shifts respectively.
Arithmetic shifts can be useful as efficient ways to perform 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 2
''n''. Shifting right by ''n'' bits on a
two's complement
Two's complement is the most common method of representing signed (positive, negative, and zero) integers on computers, and more generally, fixed point binary values. Two's complement uses the binary digit with the ''greatest'' value as the ''s ...
''signed'' binary number has the effect of dividing it by 2
''n'', 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 a number of compilers.
For example, in the
x86 instruction set
The x86 instruction set refers to the set of instructions that x86-compatible microprocessors support. The instructions are usually part of an executable program, often stored as a computer file and executed on the processor.
The x86 instructi ...
, the SAR instruction (arithmetic right shift) divides a signed number by a power of two, rounding towards negative infinity. 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.
Formal definition
The formal definition of an arithmetic shift, from
Federal Standard 1037C is that it is:
An important word in the FS 1073C definition is "usually".
Non-equivalence of arithmetic right shift and division
However, arithmetic ''right'' shifts are major traps for the unwary, specifically in treating rounding of negative integers. For example, in the usual
two's complement
Two's complement is the most common method of representing signed (positive, negative, and zero) integers on computers, and more generally, fixed point binary values. Two's complement uses the binary digit with the ''greatest'' value as the ''s ...
representation of negative integers, −1 is represented as all 1's. For an 8-bit signed integer this is 1111 1111. An arithmetic right-shift by 1 (or 2, 3, ..., 7) yields 1111 1111 again, which is still −1. This corresponds to rounding down (towards negative infinity), but is not the usual convention for division.
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 faster than division instructions.) Large number of 1960s and 1970s programming handbooks, manuals, and other specifications from companies and institutions such as
DEC,
IBM
International Business Machines Corporation (using the trademark IBM), nicknamed Big Blue, is an American Multinational corporation, multinational technology company headquartered in Armonk, New York, and present in over 175 countries. It is ...
,
Data General
Data General Corporation was an early minicomputer firm formed in 1968. Three of the four founders were former employees of Digital Equipment Corporation (DEC).
Their first product, 1969's Data General Nova, was a 16-bit minicomputer intended to ...
, and
ANSI
The American National Standards Institute (ANSI ) is a private nonprofit organization that oversees the development of voluntary consensus standards for products, services, processes, systems, and personnel in the United States. The organiz ...
make such incorrect statements.
Logical right shifts are equivalent to division by a power of the radix (usually 2) only for positive or unsigned numbers. Arithmetic right shifts are equivalent to logical right shifts for positive signed numbers. Arithmetic right shifts for negative numbers in N's complement (usually
two's complement
Two's complement is the most common method of representing signed (positive, negative, and zero) integers on computers, and more generally, fixed point binary values. Two's complement uses the binary digit with the ''greatest'' value as the ''s ...
) is roughly equivalent to division by a power of the radix (usually 2), where for odd numbers rounding downwards is applied (not towards 0 as usually expected).
Arithmetic right shifts for negative numbers are equivalent to division using rounding towards 0 in
ones' complement
The ones' complement of a binary number is the value obtained by inverting (flipping) all the bits in the Binary number, binary representation of the number. The name "ones' complement" refers to the fact that such an inverted value, if added t ...
representation of signed numbers as was used by some historic computers, but this is no longer in general use.
Handling the issue in programming languages
The (1999) ISO standard for the programming language
C defines the right shift operator in terms of divisions by powers of 2. Because of the above-stated non-equivalence, the standard explicitly excludes from that definition the right shifts of signed numbers that have negative values. It does not specify the behaviour of the right shift operator in such circumstances, but instead requires each individual C compiler to define the behaviour of shifting negative values right.
Like C, C++ had an implementation-defined right shift for signed integers until C++20. Starting in the C++20 standard, right shift of a signed integer is defined to be an arithmetic shift.
Applications
In applications where consistent rounding down is desired, arithmetic right shifts for signed values are useful. An example is in
downscaling raster coordinates by a power of two, which maintains even spacing. For example, right shift by 1 sends 0, 1, 2, 3, 4, 5, ... to 0, 0, 1, 1, 2, 2, ..., and −1, −2, −3, −4, ... to −1, −1, −2, −2, ..., maintaining even spacing as −2, −2, −1, −1, 0, 0, 1, 1, 2, 2, ... In contrast, integer division with rounding towards zero sends −1, 0, and 1 all to 0 (3 points instead of 2), yielding −2, −1, −1, 0, 0, 0, 1, 1, 2, 2, ... instead, which is irregular at 0.
Notes
References
Cross-reference
Sources used
*
*
*
*
*
*
*
{{DEFAULTSORT:Arithmetic Shift
Binary arithmetic
Operators (programming)