Quelle est la différence entre les opérateurs >>>
et >>
en Java?
>>
est un décalage arithmétique à droite, >>>
est un décalage logique à droite.
Dans un décalage arithmétique, le bit de signe est étendu pour préserver la signature du nombre.
Par exemple: -2 représenté sur 8 bits correspondrait à 11111110
(car le bit de poids fort a un poids négatif). En le décalant d'un bit en utilisant un décalage arithmétique, vous obtiendrez 11111111
, ou -1. Logical right shift, cependant, ne se soucie pas que la valeur puisse éventuellement représenter un nombre signé; il déplace tout simplement vers la droite et remplit par la gauche avec des 0. Décaler notre -2 un bit à droite en utilisant un décalage logique donnerait 01111111
.
>>>
est unsigned-shift; il insérera 0. >>
est signé et étend le bit de signe.
Les opérateurs de décalage comprennent le décalage à gauche
<<
, le décalage à droite signé>>
et le décalage à droite non signé>>>
.La valeur de
n>>s
estn
le bit déplacé à droites
se positionne avec extension de signe .La valeur de
n>>>s
estn
le bit déplacé à droites
se positionne avec une extension nulle .
System.out.println(Integer.toBinaryString(-1));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >> 16));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >>> 16));
// prints "1111111111111111"
Pour rendre les choses plus claires en ajoutant une contrepartie positive
System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"
Comme il est positif, les décalages signés et non signés ajouteront 0 au bit le plus à gauche.
1 >>> 32 == 1
Ils sont tous deux à droite, mais >>>
est unsigned
De la documentation :
L'opérateur de décalage droit non signé ">>>" décale le zéro dans la position la plus à gauche, tandis que la position la plus à gauche après ">>" dépend de l'extension du signe.
>>>
mettra toujours un 0 dans le bit le plus à gauche, tandis que >>
mettra un 1 ou un 0 en fonction de son signe.
Le décalage logique à droite (v >>> n
) renvoie une valeur dans laquelle les bits de v
ont été décalés vers la droite de n
positions de bits et les 0 sont décalés du côté gauche. Envisagez de décaler les valeurs 8 bits, écrites en binaire:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
Si nous interprétons les bits comme un entier non négatif non signé, le décalage logique à droite a pour effet de diviser le nombre par la puissance correspondante de 2. Toutefois, si le nombre est dans la représentation du complément à deux, le décalage logique à droite ne divise pas correctement les nombres négatifs . Par exemple, le deuxième décalage à droite ci-dessus passe de 128 à 32 lorsque les bits sont interprétés comme des nombres non signés. Mais il passe de -128 à 32 lorsque, comme c'est typique en Java, les bits sont interprétés en complément à deux.
Par conséquent, si vous vous déplacez pour diviser par une puissance de deux, vous voulez le décalage arithmétique à droite (v >> n
). Il renvoie une valeur dans laquelle les bits de v
ont été décalés vers la droite de n
positions de bits, et les copies de le bit le plus à gauche de v sont décalées de gauche côté:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Lorsque les bits sont un nombre dans la représentation du complément à deux, le décalage à droite arithmétique a pour effet de diviser par une puissance de deux. Cela fonctionne car le bit le plus à gauche est le bit de signe. La division par une puissance de deux doit garder le signe identique.
En savoir plus sur Opérateurs de bits et bits
>> Signed right shift
>>> Unsigned right shift
La configuration de bits est donnée par l'opérande de gauche et le nombre de positions à déplacer par l'opérande de droite. L'opérateur de décalage droit non signé >>>
déplace un zéro vers la position la plus à gauche ,
tandis que la position la plus à gauche après >>
dépend de l’extension du signe.
En termes simples, >>>
toujours déplace un zéro à la position la plus à gauche alors que >>
se déplace en fonction du signe du nombre, à savoir 1 pour le nombre négatif et 0 pour le nombre positif.
Par exemple, essayez avec des nombres négatifs et positifs.
int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));
System.out.println();
c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
sortie:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
L'opérateur logique de décalage à droite (>>> N
) décale les bits vers la droite de N positions, en ignorant le bit de signe et en complétant les N bits les plus à gauche avec des 0. Par exemple:
-1 (in 32-bit): 11111111111111111111111111111111
après une opération >>> 1
devient:
2147483647: 01111111111111111111111111111111
L'opérateur arithmétique de décalage à droite (>> N
) décale également les bits vers la droite de N positions, mais conserve le bit de signe et complète les N bits les plus à gauche avec des 1. Par exemple:
-2 (in 32-bit): 11111111111111111111111111111110
après une opération >> 1
devient:
-1: 11111111111111111111111111111111