Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无符号右移运算符“的用途是什么?”&燃气轮机&燃气轮机&燃气轮机&引用;在爪哇?_Java_Programming Languages_Bit Manipulation - Fatal编程技术网

Java 无符号右移运算符“的用途是什么?”&燃气轮机&燃气轮机&燃气轮机&引用;在爪哇?

Java 无符号右移运算符“的用途是什么?”&燃气轮机&燃气轮机&燃气轮机&引用;在爪哇?,java,programming-languages,bit-manipulation,Java,Programming Languages,Bit Manipulation,我理解Java中无符号右移位运算符“>>>”的功能,但为什么我们需要它,为什么我们不需要相应的无符号左移位运算符?基本上这与符号(数字移位)或无符号移位(通常与像素相关的内容)有关 由于左移位不处理符号位,因此也是一样(使用>运算符可以将int和long视为32位和64位无符号整数类型,Java语言中缺少这些类型 当您移动不表示数值的内容时,这非常有用。例如,您可以使用32位ints来表示黑白位图图像,其中每个int对屏幕上的32个像素进行编码。如果您需要向右滚动图像,您更喜欢ints左侧的位变

我理解Java中无符号右移位运算符“>>>”的功能,但为什么我们需要它,为什么我们不需要相应的无符号左移位运算符?

基本上这与符号(数字移位)或无符号移位(通常与像素相关的内容)有关


由于左移位不处理符号位,因此也是一样(使用
>
运算符可以将
int
long
视为32位和64位无符号整数类型,Java语言中缺少这些类型

当您移动不表示数值的内容时,这非常有用。例如,您可以使用32位
int
s来表示黑白位图图像,其中每个
int
对屏幕上的32个像素进行编码。如果您需要向右滚动图像,您更喜欢
int
s左侧的位变为零,以便您可以轻松地将相邻
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;
 }
int-shiftBy=3;
int[]imageRow=。。。
int shiftCarry=0;
//最后一个移位位设置为1,其余为0
int mask=(1>>移位)|(进位>>
运算符生成它们


没有相应的
负数的正常右移
>
将使其保持为负数。即,符号位将保留

无符号的右移位
>
也将移位符号位,并将其替换为零位

不需要有等效的左移位,因为只有一个符号位,它是最左边的位,所以它只在右移位时发生干扰

本质上,区别在于一个保留符号位,另一个移位为零以替换符号位

对于正数,它们的作用相同


有关同时使用
>
>
的示例,请参阅。

如果一个人有一个表示数字的
int
,并且希望将其除以二的幂,向负无穷大舍入,则有符号右移运算符非常有用。这在进行缩放坐标等显示操作时非常有用;不仅如此比除法快,但在缩放前因比例因子不同而不同的坐标在缩放后将相差一个像素。如果不使用移位,则使用除法,则不起作用。例如,当按两个因子进行缩放时,-1和+1相差两个,因此应在缩放后相差一个,但-1/2=0和1/2=0。如果相反,使用符号如果右移,结果会很好:-1>>1=-1和1>>1=0,正确地产生相隔一个像素的值

无符号运算符在以下情况下很有用:输入预期正好有一个位集,并且希望结果也有一个位集,或者使用循环输出字中的所有位,并希望它干净地终止。例如:

void processBitsLsbFirst(int n, BitProcessor whatever)
{
  while(n != 0)
  {
    whatever.processBit(n & 1);
    n >>>= 1;
  }
}
如果代码使用有符号右移运算并传递负值,它将无限期地输出1。但是,使用无符号右移运算符,最高有效位的解释结果与其他任何位一样

无符号右移运算符在以下情况下也很有用:从算术上讲,计算将产生一个介于0和4294967295之间的正数,并且希望将该数字除以二的幂。例如,当计算已知为正数的两个
int
值之和时,可以使用
(n1+n2)>>>1
无需将操作数提升为
。此外,如果希望在不使用浮点数学的情况下将正的
int
值除以类似pi的值,则可以计算
((value*5468522205L)>>34)
[(1L
也是找到两个四舍五入平均值的安全有效方法(大)整数:

int mid = (low + high) >>> 1;
如果整数
high
low
接近最大的机器整数,则上述结果是正确的,但

int mid = (low + high) / 2;
由于溢出,可能会得到错误的结果


下面是一个简单的例子,修复了简单二进制搜索中的一个bug。

在Java域中,大多数典型的应用程序避免溢出的方法是使用强制转换或大整数,如前面示例中的int-to-long

int hiint = 2147483647;
System.out.println("mean hiint+hiint/2 = " + ( (((long)hiint+(long)hiint)))/2);
System.out.println("mean hiint*2/2 = " + ( (((long)hiint*(long)2)))/2);

BigInteger bhiint = BigInteger.valueOf(2147483647);
System.out.println("mean bhiint+bhiint/2 = " + (bhiint.add(bhiint).divide(BigInteger.valueOf(2))));

你所说的“处理”是什么意思?我在代码中一直使用32位无符号值,而且我从不使用>>>运算符。@TylerDurden没有
>>
(例如,当你使用
>
)最高有效位(也称为“符号位”)32位或64位值的符号将得到特殊处理-它在移位后被复制到新的符号位,因此
>
移位后的值的符号保持不变。对于具有符号的语言(例如C/C++或C#)中的无符号类型,这是不同的。在这些语言中,符号位的内容由第一个操作数的类型控制。由于Java中没有无符号类型,因此该语言最终引入了一个特殊的无符号“右移”运算符.对,正如我所说,我知道它是做什么的。为什么?你关心的是什么情况?@TylerDurden-例如,在
BigInteger
中,它使用一个整数数组来存储它的数字。要右移,它将使用
>
来右移,除了最重要的数字。实际上,没有
也不需要索引d、 我是在评论你的措辞,这可能会给新手一个相反的建议:“这是一样的(
当你移植的C代码对无符号整数进行右移时,你最好使用>>>,否则会得到错误的结果。找到平均值的好信息。但是”会引发异常“-不会引发异常,但会由于溢出而导致意外结果精彩的解释!Joshua Bloch在”“”“中给出了此用法的一个示例,修复了朴素二进制搜索中的一个错误。的可能重复项。”