What are the exact semantics of Rust's shift operators?

ⅰ亾dé卋堺 提交于 2019-12-08 15:57:48

问题


I tried to find exact information about how the << and >> operators work on integers, but I couldn't find a clear answer (the documentation is not that great in that regard).

There are two parts of the semantics that are not clear to me. First, what bits are "shifted in"?

  • Zeroes are shifted in from one side (i.e. 0b1110_1010u8 << 4 == 0b1010_0000u8), or
  • the bits rotate (i.e. 0b1110_1010u8 << 4 == 0b1010_1110u8), or
  • it's unspecified (like overflowing behavior of integers is unspecified), or
  • something else.

Additionally, how does shifts work with signed integers? Is the sign bit also involved in the shift or not? Or is this unspecified?


回答1:


What are the exact semantics of Rust's shift operators?

There are none. The shift operators are a user-implementable trait and you can do basically anything you want in them. The documentation even shows an example of "[a]n implementation of Shr that spins a vector rightward by a given amount."


how the << and >> operators work on integers,

The reference has a section on Arithmetic and Logical Binary Operators. Most usefully, it contains this footnote:

Arithmetic right shift on signed integer types, logical right shift on unsigned integer types.

Logical shifting and arithmetic shifting are preexisting computer science terms with established definitions.

Zeroes are shifted in

Yes.

the bits rotate

No. There are separate methods for rotating left and right.




回答2:


The thin documentation on the traits Shl and Shr is intentional, so that they may adopt a behaviour that is most suitable for the type at hand (think newtypes!).

With that said, when it comes to the base integer types, the Rust reference covers how they behave, with a bit of inference:

  • << | Left Shift | std::ops::Shl

  • >> | Right Shift* | std::ops::Shr

* Arithmetic right shift on signed integer types, logical right shift on unsigned integer types.

It also includes a few examples, which further clarifies that these are conventional logical/arithmetic shifts: zeros are inserted to the least significant bits on a left bit shift, and the most significant bit is extended for signed integers on a right bit shift. It is also not a rotation, as described in the methods rotate_left and rotate_right.

assert_eq!(13 << 3, 104);
assert_eq!(-10 >> 2, -3);

Moreover, shifting too many bits may be regarded as an arithmetic overflow, and is not undefined behaviour. See: Is it expected that a too large bitshift is undefined behavior in Rust?



来源:https://stackoverflow.com/questions/51571066/what-are-the-exact-semantics-of-rusts-shift-operators

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!