什么">>>"在java中意味着什么?

eag*_*arn 31 java arrays primitive

我发现此代码在SO帖子中找到重复项.但我不明白这条线的含义int mid = (low + high) >>> 1;

private static int findDuplicate(int[] array) {
        int low = 0;
        int high = array.length - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            System.out.println(mid);
            int midVal = array[mid];

            if (midVal == mid)
                low = mid + 1;
            else
                high = mid - 1;
        }
        return high;
    }
Run Code Online (Sandbox Code Playgroud)

rge*_*man 77

>>>操作是在Java中无符号的右位移运算符.它有效地将操作数除以2右操作数的幂,或者只是2在这里.

之间的差异>>>>>转移负数时,只会出现.该>>运营商移动一个1位成为最显著位,如果它是一个1,而>>>在转变0不管.

更新:

我们的平均值12147483647(Integer.MAX_VALUE).我们可以轻松地进行数学运算:

(1 + 2147483647) / 2 = 2147483648 / 2 = 1073741824
Run Code Online (Sandbox Code Playgroud)

现在,使用代码(low + high) / 2,这些是涉及的位:

          1: 00000000 00000000 00000000 00000001
+2147483647: 01111111 11111111 11111111 11111111
================================================
-2147483648: 10000000 00000000 00000000 00000000  // Overflow
/2
================================================
-1073741824: 11000000 00000000 00000000 00000000  // Signed divide, same as >> 1.
Run Code Online (Sandbox Code Playgroud)

让我们"转变"为>>>:

          1: 00000000 00000000 00000000 00000001
+2147483647: 01111111 11111111 11111111 11111111
================================================
-2147483648: 10000000 00000000 00000000 00000000  // Overflow
>>> 1
================================================
+1073741824: 01000000 00000000 00000000 00000000  // Unsigned shift right.
Run Code Online (Sandbox Code Playgroud)

  • @你能举个例子来说明一下吗?那会很有帮助的 (2认同)
  • 正如我所说明的,在Java中,它们在溢出的情况下并不等效。 (2认同)
  • 是的,`>>>`将值视为无符号.如果值是无符号的,则不会发生溢出.移位时,该值不再超过最大`int`值,并且可以再次正确解释为有符号值. (2认同)

Pet*_*rey 38

的意义

int mid = (low + high) >>> 1;
Run Code Online (Sandbox Code Playgroud)

是; 通过使用无符号移位,它避免了导致负数的溢出.这是必需的,因为Java不支持unsigned int值.(BTW char未签名)

写这个的传统方式是

int mid = (low + high) / 2; // don't do this
Run Code Online (Sandbox Code Playgroud)

然而,这可能会溢出更大的金额,你得到一个负数中期.

例如

int high = 2100000000;
int low = 2000000000;
System.out.println("mid using >>> 1 = " + ((low + high) >>> 1));
System.out.println("mid using / 2   = " + ((low + high) / 2));
Run Code Online (Sandbox Code Playgroud)

版画

mid using >>> 1 = 2050000000
mid using / 2   = -97483648
Run Code Online (Sandbox Code Playgroud)

显然第二个结果是不正确的.

  • +1; 非常细心(并且适当)指出 char 的无符号性。 (2认同)

小智 6

它是一个按位运算符 .. 它适用于位值。假设如果 A 为 60,则 A>>>2 将给出 15(位值 0000 1111)

它的实际名称是“右移零运算符”,此处左操作数的值向右移动右操作数指定的位数(在本例中为 2),移位后的值用零 (0000) 填充。