Réponses:
>>
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 conserver la signature du nombre.
Par exemple: -2 représenté sur 8 bits serait 11111110
(car le bit le plus significatif a un poids négatif). Le déplacer d'un bit vers la droite en utilisant le décalage arithmétique vous donnerait 11111111
, ou -1. Le décalage à droite logique, 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 à partir de la gauche avec des 0. Décaler notre bit de droite de -2 en utilisant le décalage logique donnerait 01111111
.
2^k
, je trouve bizarre que ce soit la réponse de tout le monde. Une chaîne de bits n'est pas un nombre et >>
peut toujours être utilisée sur n'importe quelle chaîne de bits: elle fait toujours la même chose quel que soit le rôle que joue cette chaîne de bits et qu'elle ait ou non un concept de `` signe ''. Serait-il correct d'étendre votre réponse déjà excellente avec une discussion sur le cas où votre opérande n'est pas interprété comme un numéro signé? Ma plainte est-elle logique?
String
pourrait aussi être considéré comme un char[]
. Il ne dit pas que a char
n'est pas un nombre; il dit juste que c'est un numéro non signé . Je pense que c'est là qu'il a perdu.
>>>
est shift non signé; il insérera 0. >>
est signé et étendra le bit de signe.
Les opérateurs de décalage incluent le décalage gauche
<<
, le décalage droit signé>>
et le décalage droit non signé>>>
.La valeur de
n>>s
est des positions de bitsn
décalées vers la droites
avec extension de signe .La valeur de
n>>>s
est des positions de bitsn
décalées vers la droites
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"
Puisqu'il est positif, les décalages signés et non signés ajouteront 0 au bit le plus à gauche.
1 >>> 32 == 1
Ils sont à la fois décalage vers la droite, mais >>>
estunsigned
De la documentation :
L'opérateur de décalage à droite non signé ">>>" décale un zéro dans la position la plus à gauche, tandis que la position la plus à gauche après ">>" dépend de l'extension du signe.
>>>
n'est pas signé, mais pourquoi 7>>32=7
? J'ai couru une boucle qui a fait un changement à la fois et j'ai vu qu'après les 32
changements, elle est revenue 7
. La seule façon pour que cela ait un sens est que pour chaque nombre déplacé, il entre dans un «cercle extérieur». Après les 32
quarts de travail, il a retrouvé sa position, mais de toute évidence cela n'a toujours pas de sens. Que se passe-t-il?
Le décalage logique vers la droite ( v >>> n
) renvoie une valeur dans laquelle les bits v
ont été décalés vers la droite par n
des positions de bits, et les 0 sont décalés du côté gauche. Pensez à 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 à droite logique a pour effet de diviser le nombre par la puissance correspondante de 2. Cependant, si le nombre est en représentation à complément à deux, le décalage à droite logique ne divise pas correctement les nombres négatifs . Par exemple, le deuxième décalage à droite ci-dessus décale 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 généralement le cas 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 v
ont été décalés vers la droite par n
des positions binaires, et des copies du bit le plus à gauche de v sont décalées du côté gauche:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Lorsque les bits sont un nombre en représentation du complément à deux, le décalage arithmétique vers la droite 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 conserver le même signe.
En savoir plus sur les opérateurs Bitwise et Bit Shift
>> Signed right shift
>>> Unsigned right shift
La configuration binaire est donnée par l'opérande de gauche et le nombre de positions à décaler par l'opérande de droite. L'opérateur de décalage à droite non signé >>>
décale un zéro dans la position la plus à gauche ,
tandis que la position la plus à gauche après >>
dépend de l'extension du signe.
En termes simples, décale>>>
toujours un zéro dans la position la plus à gauche tandis que >>
décale en fonction du signe du nombre, c'est-à-dire 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));
production:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0'))
:; Integer.MAX_VALUE : 01111111111111111111111111111111;
Integer.MIN_VALUE : 10000000000000000000000000000000;
-1 : 11111111111111111111111111111111;
0 : 00000000000000000000000000000000;
1 : 00000000000000000000000000000001
L'opérateur logique de décalage à droite ( >>> N
) décale les bits vers la droite de N positions, supprimant le bit de signe et remplissant les N bits les plus à gauche par des 0. Par exemple:
-1 (in 32-bit): 11111111111111111111111111111111
après qu'une >>> 1
opération 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 préserve le bit de signe et remplit les N bits les plus à gauche par des 1. Par exemple:
-2 (in 32-bit): 11111111111111111111111111111110
après qu'une >> 1
opération devient:
-1: 11111111111111111111111111111111