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
Bitwise operation
(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!
=== In high-level languages === {{further|Circular shift#Implementing circular shifts}} ==== In C family of languages ==== {{anchor|Shifts in C family of languages}} In C and C++ languages, the logical shift operators are "<code><<</code>" for left shift and "<code>>></code>" for right shift. The number of places to shift is given as the second argument to the operator. For example, <syntaxhighlight lang="c">x = y << 2;</syntaxhighlight> assigns <code>x</code> the result of shifting <code>y</code> to the left by two bits, which is equivalent to a multiplication by four. Shifts can result in implementation-defined behavior or [[undefined behavior]], so care must be taken when using them. The result of shifting by a bit count greater than or equal to the word's size is undefined behavior in C and C++.<ref name=":0" /><ref>{{Cite web|url=http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators|title=Arithmetic operators - cppreference.com|website=en.cppreference.com|access-date=2016-07-06}}</ref> Right-shifting a negative value is implementation-defined and not recommended by good coding practice;<ref>{{cite web|title=INT13-C. Use bitwise operators only on unsigned operands|url=https://www.securecoding.cert.org/confluence/display/c/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands|website=CERT: Secure Coding Standards|publisher=Software Engineering Institute, Carnegie Mellon University|access-date=7 September 2015}}</ref> the result of left-shifting a signed value is undefined if the result cannot be represented in the result type.<ref name=":0">[http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n843.htm JTC1/SC22/WG14 N843 "C programming language"], section 6.5.7</ref> In C#, the right-shift is an arithmetic shift when the first operand is an int or long. If the first operand is of type uint or ulong, the right-shift is a logical shift.<ref>{{cite web|url=http://msdn.microsoft.com/en-us/library/xt18et0d%28v=vs.110%29.aspx|title=Operator (C# Reference)|access-date=14 July 2013|publisher=Microsoft}}</ref> =====Circular shifts===== {{anchor|Circular shifts in C-family languages}} The C-family of languages lack a rotate operator (although C++20 provides <code>std::rotl</code> and <code>std::rotr</code>), but one can be synthesized from the shift operators. Care must be taken to ensure the statement is well formed to avoid [[undefined behavior]] and [[timing attack]]s in software with security requirements.<ref name="StackOverflow">{{cite web|url=https://stackoverflow.com/q/31387778|title=Near constant time rotate that does not violate the standards?|access-date=12 August 2015|publisher=Stack Exchange Network}}</ref> For example, a naive implementation that left-rotates a 32-bit unsigned value <code>x</code> by <code>n</code> positions is simply <syntaxhighlight lang="c"> uint32_t x = ..., n = ...; uint32_t y = (x << n) | (x >> (32 - n)); </syntaxhighlight> However, a shift by <code>0</code> bits results in undefined behavior in the right-hand expression <code>(x >> (32 - n))</code> because <code>32 - 0</code> is <code>32</code>, and <code>32</code> is outside the range 0β31 inclusive. A second try might result in <syntaxhighlight lang="c"> uint32_t x = ..., n = ...; uint32_t y = n ? (x << n) | (x >> (32 - n)) : x; </syntaxhighlight> where the shift amount is tested to ensure that it does not introduce undefined behavior. However, the branch adds an additional code path and presents an opportunity for timing analysis and attack, which is often not acceptable in high-integrity software.<ref name="StackOverflow" /> In addition, the code compiles to multiple machine instructions, which is often less efficient than the processor's native instruction. To avoid the undefined behavior and branches under [[GNU Compiler Collection|GCC]] and [[Clang]], the following is recommended. The pattern is recognized by many compilers, and the compiler will emit a single rotate instruction:<ref>{{cite web|url=https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157|title=Poor optimization of portable rotate idiom|access-date=11 August 2015|publisher=GNU GCC Project}}</ref><ref>{{cite web|url=https://software.intel.com/en-us/forums/topic/580884|title=Circular rotate that does not violate C/C++ standard?|access-date=12 August 2015|publisher=Intel Developer Forums}}</ref><ref name=LLVM>{{cite web|url=https://llvm.org/bugs/show_bug.cgi?id=24226|title=Constant not propagated into inline assembly, results in "constraint 'I' expects an integer constant expression"|access-date=11 August 2015|publisher=LLVM Project}}</ref> <syntaxhighlight lang="c"> uint32_t x = ..., n = ...; uint32_t y = (x << n) | (x >> (-n & 31)); </syntaxhighlight> There are also compiler-specific [[Intrinsic function|intrinsics]] implementing [[circular shift]]s, like [http://msdn.microsoft.com/en-us/library/t5e2f3sc(VS.80).aspx _rotl8, _rotl16], [http://msdn.microsoft.com/en-us/library/yy0728bz(VS.80).aspx _rotr8, _rotr16] in Microsoft [[Visual C++]]. Clang provides some rotate intrinsics for Microsoft compatibility that suffers the problems above.<ref name=LLVM /> GCC does not offer rotate intrinsics. Intel also provides x86 [https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=rot&techs=Other intrinsics]. ==== Java ==== {{anchor|Shifts in Java}} In [[Java (programming language)|Java]], all integer types are signed, so the "<code><<</code>" and "<code>>></code>" operators perform arithmetic shifts. Java adds the operator "<code>>>></code>" to perform logical right shifts, but since the logical and arithmetic left-shift operations are identical for signed integer, there is no "<code><<<</code>" operator in Java. More details of Java shift operators:<ref>The Java Language Specification, section [http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19 15.19. Shift Operators]</ref> * The operators <code><<</code> (left shift), <code>>></code> (signed right shift), and <code>>>></code> (unsigned right shift) are called the ''shift operators''. * The type of the shift expression is the promoted type of the left-hand operand. For example, <code>aByte >>> 2</code> is equivalent to {{code|2=java|((int) aByte) >>> 2}}. * If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & with the mask value 0x1f (0b11111).<ref name="jls15.22.1">{{cite web|url=http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.1|title=Chapter 15. Expressions|website=oracle.com}}</ref> The shift distance actually used is therefore always in the range 0 to 31, inclusive. * If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & with the mask value 0x3f (0b111111).<ref name="jls15.22.1"/> The shift distance actually used is therefore always in the range 0 to 63, inclusive. * The value of {{code|n >>> s}} is ''n'' right-shifted ''s'' bit positions with zero-extension. * In bit and shift operations, the type <code>''byte''</code> is implicitly converted to <code>''int''</code>. If the byte value is negative, the highest bit is one, then ones are used to fill up the extra bytes in the int. So {{code|1=byte b1 = -5; int i = b1 {{!}} 0x0200;|2=java}} will result in {{code|1=i == -5}}. ==== JavaScript ==== {{anchor|Shifts in JavaScript}} [[JavaScript]] uses bitwise operations to evaluate each of two or more [[units place]] to 1 or 0.<ref>[https://www.w3schools.com/js/js_bitwise.asp "JavaScript Bitwise"]. ''W3Schools.com''.</ref> ==== Pascal ==== {{anchor|Shifts in Pascal}} In Pascal, as well as in all its dialects (such as [[Object Pascal]] and [[GNU Pascal|Standard Pascal]]), the logical left and right shift operators are "<code>shl</code>" and "<code>shr</code>", respectively. Even for signed integers, <code>shr</code> behaves like a logical shift, and does not copy the sign bit. The number of places to shift is given as the second argument. For example, the following assigns ''x'' the result of shifting ''y'' to the left by two bits: <syntaxhighlight lang="pascal">x := y shl 2;</syntaxhighlight>
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)