56

我在此处的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;
    }
4

3 回答 3

116

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

>>和之间的差异>>>只会在移动负数时出现。如果它是 a ,则>>运算符将一位1移入最高有效位,并且无论如何都移入a 。1>>>0

更新:

让我们平均12147483647( Integer.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.
于 2013-09-27T19:44:22.067 回答
57

的意义

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

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

写这个的传统方式是

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

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

于 2013-09-27T19:47:07.893 回答
7

它是按位运算符.. 它适用于位值。假设如果 A 保持 60,那么 A>>>2 将给出 15(位值 0000 1111)

它的实际名称是“右移零运算符”,这里左操作数的值右移了右操作数指定的位数(在这种情况下为 2),移位后的值用零(0000)填充。

于 2013-09-27T19:50:31.827 回答