Scala中的>>和>>>运算符有什么区别吗?
scala> 0x7f >>> 1
res10: Int = 63
scala> 0x7f >> 1
res11: Int = 63
scala> 0x7f >> 4
res12: Int = 7
scala> 0x7f >>> 4
res13: Int = 7
>>
运算符保留符号(符号扩展),同时将>>>
最左边的位归零(零扩展)。
-10>>2
res0: Int = -3
-10>>>2
res1: Int = 1073741821
这在像 C 这样具有有符号和无符号类型的语言中是不必要的,与 Java 不同,Java 也有>>>
(因为它没有无符号整数)。
它们与 Java 中的含义相同。
有符号左移运算符“<<”将位模式左移,有符号右移运算符“>>”将位模式右移。位模式由左侧操作数给出,而要移位的位置数由右侧操作数给出。无符号右移运算符“>>>”将零移到最左边的位置,而“>>”之后的最左边的位置取决于符号扩展。
>>>
仅存在于 Java 中,而不存在于 C 或 C++ 中。
注意:使用SLIP 30(2015 年 11 月),Scala 可能最终(在 2016 年?2017 年?)使用 4 种“原始”类型来表示无符号整数:UByte
、UShort
和.UInt
ULong
这将影响UInts 和 ULongs 上的位移操作>>
,这也说明了和之间的区别>>>
:
左移
<<
和逻辑右移>>>
以明显的方式表现。算术右移的情况
>>
是有争议的。
我们认为它不应该在无符号整数上可用,原因有两个:
- 首先,算术右移似乎对无符号整数没有任何意义。正确的算术移位 if
>>>
。因此,与 类似unary_-
,不应引入。- 其次,确实具有无符号整数类型的现有语言,例如 C 系列,实际上
>>
根据它是否具有有符号或无符号操作数给出不同的语义:无符号操作数上的
A>>
不会符号扩展。在 Scala 中进行符号扩展会让 C 开发人员感到困惑x >> 3
,但对于不进行符号扩展的 Scala 开发人员来说,同样会感到困惑x >> 3
。因此,我们宁愿将其完全省略,并引发编译器错误。如果基于位旋转的算法需要符号扩展右移,则始终可以重新解释为有符号,执行操作,然后重新解释为无符号:
(x.toInt >> 3).toUInt
。注意:当前的实现确实提供了
>>
,直到我们在这一点上达成一致。