Difference between >> and >>> in Scala
Is there any difference between >> and >>> operator in 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
Solution 1:
The >>
operator preserves the sign (sign-extends), while >>>
zeroes the leftmost bits (zero-extends).
-10>>2
res0: Int = -3
-10>>>2
res1: Int = 1073741821
Try it out yourself.
This is not necessary in languages like C which has signed and unsigned types, unlike Java, which also has >>>
(because it has no unsigned integers).
Solution 2:
They have the same meaning as in Java.
From The Java™ Tutorials - Bitwise and Bit Shift Operators:
The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.
>>>
only exists in Java, but not C or C++.
Solution 3:
Note: with SLIP 30 (Nov. 2015), Scala might end up (in 2016? 2017?) with 4 "primitive" types to represent unsigned integers: UByte
, UShort
, UInt
and ULong
.
That would impact Bit shifting operations on UInts and ULongs, which also illustrates the difference between >>
and >>>
:
Shift left
<<
and shift logical right>>>
behave in the obvious way.The case of shift arithmetic right
>>
is debatable.
We argue that it should not be available on unsigned integers for two reasons:
- First, a shift arithmetic right does not appear to have any meaning on unsigned integers. The correct arithmetic shift if
>>>
. Therefore, similarly tounary_-
, it should not be introduced.- Second, existing languages that do have unsigned integer types, such as the C family, actually give different semantics to
>>
depending on whether it has a signed or unsigned operand:
A>>
on an unsigned operand does not sign-extend. It would be confusing to a C developer forx >> 3
to sign-extend in Scala, but it would be equally confusing to a Scala developer thatx >> 3
not sign-extend. Therefore, we prefer to leave it out completely, and let a compiler error be raised.If a bit-twiddling-based algorithm needs the sign-extending shift right, it is always possible to reinterpret as signed, do the operation, and reinterpret back as unsigned:
(x.toInt >> 3).toUInt
.Note: the current implementation does provide
>>
, until we agree on this point.