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 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].
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)