Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Arithmetic shift
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{short description|Shift operator in computer programming}} <!--This article is in Commonwealth English--> [[Image:Rotate right arithmetically.svg|thumb|300px|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.]] [[Image:Rotate left logically.svg|thumb|300px|A left arithmetic shift of a binary number by 1. The empty position in the [[least significant bit]] is filled with a zero.]] <!-- Table arranged in rough alphabetic order of shifts. --> {| class="wikitable" style="float:right; clear:right;" |+ Arithmetic shift operators in various programming languages and processors ! Language or processor !! Left !! Right |- | style="max-width:195px" | [[ActionScript]] 3, [[Java (programming language)|Java]], [[JavaScript]], [[Python (programming language)|Python]], [[PHP]], [[Ruby (programming language)|Ruby]], [[C (programming language)|C]], [[C++]],<ref>{{Cite web|url=https://tour.dlang.org/tour/en/gems/bit-manipulation|title=Bit manipulation - Dlang Tour|website=tour.dlang.org|access-date=2019-06-23}}</ref>[[D (programming language)|D]], [[C_Sharp_(programming_language)|C#]], [[Go (programming language)|Go]], [[Julia (programming language)|Julia]],<br />[[Rust (programming language)|Rust]] (signed types only)<ref>{{Cite web|title=Operator Expressions: Arithmetic and Logical Binary Operators|url=https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators|access-date=2022-11-13|website=doc.rust-lang.org}}</ref>,<br />[[Swift (programming language)|Swift]] (signed types only)<ref group="note">The <code> >> </code> operator in C and C++ is not necessarily an arithmetic shift. Usually it is only an arithmetic shift if used with a signed integer type on its left-hand side. If it is used on an unsigned integer type instead, it will be a ''logical'' shift.</ref>||<code> << </code> || <code> >> </code> |- | [[Ada (programming language)|Ada]] || <code> Shift_Left </code><ref>{{Cite web|url=https://www.adaic.org/resources/add_content/standards/12aarm/html/AA-B-2.html|title=Annotated Ada 2012 Reference Manual}}</ref> || <code> Shift_Right_Arithmetic </code> |- | [[Kotlin (programming language)|Kotlin]] || <code> shl </code> || <code> shr </code> |- | [[Fortran]] || <code> SHIFTL </code> || <code> SHIFTA </code><ref group="note">Fortran 2008.</ref> |- | [[Standard ML]] || <code> << </code> || <code> ~>> </code> |- | [[Verilog]] || <code> <<< </code> || <code> >>> </code><ref group="note">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.</ref> |- | [[OpenVMS]] macro language | colspan="2" align="center" | @{{#tag:ref|In the [[OpenVMS]] macro language, whether an arithmetic shift is left or right 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++, have no defined behaviour if negative values are used.){{sfn|HP|2001}}{{Page needed|date=March 2012}}|group="note"}} |- | [[Scheme (programming language)|Scheme]] | colspan="2" align="center" | <code>arithmetic-shift</code><ref group="note" name="scheme">In Scheme <code>arithmetic-shift</code> can be both left and right shift, depending on the second operand, very similar to the OpenVMS macro language, although R6RS Scheme adds both <code>-right</code> and <code>-left</code> variants.</ref> |- | [[Common Lisp]] | colspan="2" align="center" | <code>ash</code> |- | [[OCaml]] || <code>lsl</code> || <code>asr</code> |- | [[Haskell (programming language)|Haskell]] | colspan="2" align="center" | <code>Data.Bits.shift</code>{{#tag:ref|The <code>Bits</code> class from Haskell's <code>Data.Bits</code> module defines both <code>shift</code> taking a signed argument and <code>shiftL</code>/<code>shiftR</code> taking unsigned arguments. These are [[isomorphic]]; for new definitions the programmer need provide only one of the two forms and the other form will be automatically defined in terms of the provided one.|group="note"}} |- | [[VHDL]] || <code>sla</code><ref group="note">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. While this is an exact mirror image of the arithmetic right shift, 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 backward 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 shift left logical (SLL) function does implement the aforementioned 'standard' arithmetic shift.</ref> || <code>sra</code> |- | Assembly: [[Z80]] || <code>SLA</code><ref>{{Cite web|url=http://www.z80.info/z80syntx.htm#SLA|title=Z80 Assembler Syntax}}</ref> || <code>SRA</code> |- | Assembly: [[x86 assembly language|x86]] || <code>SAL</code> || <code>SAR</code> |- | Assembly: [[Motorola 68000 series|68k]] || <code>ASL</code> || <code>ASR</code> |- | Assembly: [[RISC-V]] || <code>sll</code>, <code>slli</code><ref>{{Cite web|url=https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf |archive-url=https://ghostarchive.org/archive/20221009/https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf |archive-date=2022-10-09 |url-status=live|date=2019-12-13|access-date=2021-08-07|title=The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA|website=[[GitHub]] |pages=18β20}}</ref> || <code>sra</code>, <code>srai</code> |} In [[computer programming]], an '''arithmetic shift''' is a [[Bitwise_operation#Bit_shifts|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 numeral system|binary number]]s 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]]). Some authors prefer the terms ''sticky right-shift'' and ''zero-fill right-shift'' for arithmetic and logical shifts respectively.<ref> Thomas R. Cain and Alan T. Sherman. [https://web.archive.org/web/20140109191811/http://www.cisa.umbc.edu/papers/ShermanCryptologia97.pdf "How to break Gifford's cipher"]. Section 8.1: "Sticky versus Non-Sticky Bit-shifting". Cryptologia. 1997. </ref> 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<sup>''n''</sup>. Shifting right by ''n'' bits on a [[two's complement]] ''signed'' binary number has the effect of dividing it by 2<sup>''n''</sup>, 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.<ref>{{cite web|last=Steele Jr|first=Guy|title=Arithmetic Shifting Considered Harmful|url=http://dspace.mit.edu/bitstream/handle/1721.1/6090/AIM-378.pdf |archive-url=https://ghostarchive.org/archive/20221009/http://dspace.mit.edu/bitstream/handle/1721.1/6090/AIM-378.pdf |archive-date=2022-10-09 |url-status=live|publisher=MIT AI Lab|access-date=20 May 2013}}</ref> For example, in the [[x86 instruction listings|x86 instruction set]], the SAR instruction (arithmetic right shift) divides a signed number by a power of two, rounding towards negative infinity.{{sfn|Hyde|1996|loc=Β§ 6.6.2.2 SAR}} 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.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)