Rust的位移运算符具体语义是什么?

34

我试图找到关于整数上的 <<>> 操作符是如何工作的确切信息,但我没有找到清晰的答案(文档在这方面并不是很好)。

有两个语义部分对我来说不太清楚。首先,“移入”的是哪些位?

  • 从一侧移入零(即 0b1110_1010u8 << 4 == 0b1010_0000u8),或者
  • 位旋转(即 0b1110_1010u8 << 4 == 0b1010_1110u8),或者
  • 它是未指定的(就像整数溢出行为一样未指定),或者
  • 其他情况。

另外,移位操作对带符号整数的操作如何呢?符号位是否也参与了移位操作?还是这是未指定的?


2
执行 >> 操作。嗯,这确实不是非常详细的文档。我建议您打开一个问题来请求更详细的文档。 - mcarton
4
请注意,rotate_right的文档说明“请注意,这与>>不是相同的操作!”,因此至少可以从中得知>>不会旋转位。 - mcarton
2个回答

36

Rust的移位运算符确切的语义是什么?

没有固定的语义。移位运算符是用户可实现的trait,你可以在其中做任何你想做的事情。文档甚至展示了一个例子,"[通过给定的量] 实现 'Shr' 将向右旋转一个向量"。


<<>> 运算符在整数上如何工作?

参考文档有一个关于 算术和逻辑二进制运算符 的部分。最有用的是它包含了这个注脚:

对于带符号整数类型进行算术右移,对于无符号整数类型进行逻辑右移。

逻辑移位算术移位 是预先存在的计算机科学术语,具有已确定的定义。

零被移入

是的。

位会旋转

不可以。左旋和右旋有各自的方法,详见rotate_leftrotate_right


值得注意的是,仅仅将数字的左边界的位移出去并不被视为"溢出"。只有当位移的数量大于或等于位数时,才被视为溢出。 - undefined

18
特意保持对特质ShlShr的文档简洁,以便它们可以采用最适合当前类型的行为(考虑新类型!)。就基本整数类型而言,Rust参考涵盖了它们的行为,其中还包括一些推断:
- << | 左移位 | std::ops::Shl - >> | 右移位* | std::ops::Shr 在有符号整数类型上进行算术右移,在无符号整数类型上进行逻辑右移。它还包括一些示例,进一步说明这些是常规的逻辑/算术移位:在左位移时将零插入到最低有效位,对于带符号整数,在右位移时扩展最高位。它也不是旋转, 如rotate_leftrotate_right方法所描述的那样。
assert_eq!(13 << 3, 104);
assert_eq!(-10 >> 2, -3);

此外,移位过多可能被视为算术溢出,而不是未定义的行为。参见:在Rust中,过大的位移是否被视为未定义行为?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接