java中的“>>>”是什么意思?

2022-08-31 15:58:50

我在这里找到了这个代码来查找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;
    }

答案 1

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

和 之间的差异仅在移动负数时显示。如果运算符是 a,则运算符会稍微移位到最显著的位,而 a 中的移位无论如何都会移位。>>>>>>>11>>>0

更新:

让我们平均和()。我们可以很容易地做数学运算:12147483647Integer.MAX_VALUE

(1 + 2147483647) / 2 = 2147483648 / 2 = 1073741824

现在,有了代码,这些是所涉及的位:(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.

让我们将“转换”为:>>>

          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.

答案 2

其意义

int mid = (low + high) >>> 1;

是;通过使用无符号移位,它可以避免导致负数的溢出。这是必需的,因为 Java 不支持值。(BTW是无符号的)unsigned intchar

传统的写法是

int mid = (low + high) / 2; // don't do this

但是,对于较大的总和,这可能会溢出,并且您得到中间的负数。

例如:

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

指纹

mid using >>> 1 = 2050000000
mid using / 2   = -97483648

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