J'ai trouvé ce code pour trouver des doublons dans DONC poster ici. mais je ne comprends pas ce que cette ligne signifie 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;
}
Le >>>
L'opérateur est opérateur de décalage de bit à droite non signé en Java . Il divise efficacement l'opérande par 2
à la puissance de l'opérande de droite, ou simplement 2
ici.
La différence entre >>
et >>>
n'apparaîtrait que lors du déplacement de nombres négatifs. Le >>
l'opérateur décale un 1
bit dans le bit le plus significatif s'il s'agissait d'un 1
, et le >>>
décale dans un 0
indépendamment.
MISE À JOUR:
Faisons une moyenne 1
et 2147483647
(Integer.MAX_VALUE
). Nous pouvons faire le calcul facilement:
(1 + 2147483647) / 2 = 2147483648 / 2 = 1073741824
Maintenant, avec le code (low + high) / 2
, ce sont les bits impliqués:
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.
Faisons le "passage" à >>>
:
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.
L'importance de
int mid = (low + high) >>> 1;
est; en utilisant le décalage non signé, il évite les débordements qui se traduisent par un nombre négatif. Ceci est nécessaire car Java ne prend pas en charge unsigned int
valeurs. (BTW char
n'est pas signé)
La façon traditionnelle d'écrire ceci était
int mid = (low + high) / 2; // don't do this
cependant, cela pourrait déborder pour des sommes plus importantes et vous obtenez un nombre négatif pour le milieu.
par exemple.
int high = 2100000000;
int low = 2000000000;
System.out.println("mid using >>> 1 = " + ((low + high) >>> 1));
System.out.println("mid using / 2 = " + ((low + high) / 2));
impressions
mid using >>> 1 = 2050000000
mid using / 2 = -97483648
il est clair que le deuxième résultat est incorrect.
c'est un opérateur au niveau du bit .. Il fonctionne sur la valeur du bit. Supposons que si A contient 60, alors A >>> 2 donnera 15 (valeur de bit 0000 1111)
Son nom réel est "Shift Zero Right Operator" ici la valeur des opérandes de gauche est déplacée vers la droite du nombre de bits spécifié (2 dans ce cas) par l'opérande de droite et les valeurs décalées sont remplies de zéros (0000).