Tyl*_*den 28 java programming-languages bit-manipulation
我理解Java中的无符号右移运算符">>>",但为什么我们需要它,为什么我们不需要相应的无符号左移运算符?
das*_*ght 26
该>>>
运营商允许你将int
和long
为32位和64位无符号整型,这是从Java语言缺少的.
当您移动不表示数值的内容时,这非常有用.例如,您可以使用32位int
s 表示黑白位图图像,其中每个位图int
在屏幕上编码32个像素.如果你需要向右滚动图像,你会更喜欢左边的位int
变为零,这样你就可以轻松地从相邻的int
s中放置位:
int shiftBy = 3;
int[] imageRow = ...
int shiftCarry = 0;
// The last shiftBy bits are set to 1, the remaining ones are zero
int mask = (1 << shiftBy)-1;
for (int i = 0 ; i != imageRow.length ; i++) {
// Cut out the shiftBits bits on the right
int nextCarry = imageRow & mask;
// Do the shift, and move in the carry into the freed upper bits
imageRow[i] = (imageRow[i] >>> shiftBy) | (carry << (32-shiftBy));
// Prepare the carry for the next iteration of the loop
carry = nextCarry;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码没有注意高三位的内容,因为>>>
运算符会产生它们
没有相应的<<
运算符,因为有符号和无符号数据类型的左移操作是相同的.
Men*_* Lu 13
>>>
也是找到两个(大)整数的舍入均值的安全有效的方法:
int mid = (low + high) >>> 1;
Run Code Online (Sandbox Code Playgroud)
如果整数high
和low
接近最大的机器整数,上面的结果是正确的
int mid = (low + high) / 2;
Run Code Online (Sandbox Code Playgroud)
由于溢出可能会得到错误的结果.
这是一个使用示例,修复了一个天真的二进制搜索中的错误.
>>
负数的正常右移将使其保持负数。即符号位将被保留。
无符号右移>>>
也会移动符号位,并将其替换为零位。
不需要等效的左移,因为只有一个符号位,并且它是最左边的位,因此它仅在右移时产生干扰。
本质上,区别在于一个保留符号位,另一个移入零以替换符号位。
对于正数,它们的作用相同。
有关使用两者的示例>>
,>>>
请参阅BigInteger shiftRight。