Risposte:
>>
è lo spostamento aritmetico a destra, >>>
è lo spostamento logico a destra.
In uno spostamento aritmetico, il bit del segno viene esteso per preservare la significatività del numero.
Ad esempio: -2 rappresentato in 8 bit sarebbe 11111110
(perché il bit più significativo ha un peso negativo). Spostarlo a destra di un bit usando lo spostamento aritmetico ti darebbe 11111111
, o -1. Lo spostamento logico a destra, tuttavia, non importa che il valore possa rappresentare un numero con segno; sposta semplicemente tutto a destra e si riempie da 0 di sinistra. Spostare il nostro -2 a destra di un bit usando lo shift logico darebbe 01111111
.
2^k
, trovo strano che questa sia la risposta di tutti. Una stringa di bit non è un numero e >>
può sempre essere utilizzata su qualsiasi stringa di bit: fa sempre la stessa cosa indipendentemente dal ruolo che svolge la stringa di bit e indipendentemente dal fatto che abbia un concetto di "segno". Sarebbe OK estendere la tua già ottima risposta con una discussione del caso quando il tuo operando non viene interpretato come un numero con segno? La mia lamentela ha senso?
String
potrebbe anche essere considerato un char[]
. Non sta dicendo che a char
non è un numero; sta solo dicendo che è un numero senza segno . Penso che sia lì che ha perso.
>>>
è turno senza segno; inserirà 0. >>
è firmato ed estenderà il bit di segno.
Gli operatori di turno includono spostamento a sinistra
<<
, spostamento a>>
destra con segno e spostamento a destra senza segno>>>
.Il valore di
n>>s
è posizioni di bitn
spostates
a destra con estensione del segno .Il valore di
n>>>s
è posizioni di bitn
spostates
a destra con estensione zero .
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"
Per chiarire le cose aggiungendo una controparte positiva
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"
Poiché è positivo, sia i turni con segno che quelli senza segno aggiungeranno 0 al bit più a sinistra.
1 >>> 32 == 1
Sono entrambi a destra, ma lo >>>
sonounsigned
Dalla documentazione :
L'operatore di spostamento a destra senza segno ">>>" sposta uno zero nella posizione più a sinistra, mentre la posizione più a sinistra dopo ">>" dipende dall'estensione del segno.
>>>
non sia firmato, ma perché 7>>32=7
? Ho eseguito un ciclo che ha fatto un turno alla volta e ho visto che dopo i 32
turni, è tornato a 7
. L'unico modo in cui ciò potrebbe avere senso è che per ogni numero spostato, entra in un "cerchio esterno". Dopo i 32
turni, è tornato in qualche modo alla sua posizione, ma ovviamente non ha ancora senso. Cosa sta succedendo?
Lo spostamento logico a destra ( v >>> n
) restituisce un valore in cui i bit in v
sono stati spostati a destra dalle n
posizioni dei bit e gli 0 vengono spostati dal lato sinistro. Considera di spostare i valori a 8 bit, scritti in binario:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
Se interpretiamo i bit come un intero non negativo senza segno, lo spostamento logico destro ha l'effetto di dividere il numero per la potenza corrispondente di 2. Tuttavia, se il numero è nella rappresentazione del complemento a due, lo spostamento logico destro non divide correttamente i numeri negativi . Ad esempio, il secondo spostamento a destra sopra sposta da 128 a 32 quando i bit vengono interpretati come numeri senza segno. Ma passa da -128 a 32 quando, come tipico in Java, i bit vengono interpretati nel complemento a due.
Pertanto, se si sta spostando per dividere per una potenza di due, si desidera l'aritmetica spostamento a destra ( v >> n
). Restituisce un valore in cui i bit in v
sono stati spostati a destra dalle n
posizioni dei bit e le copie del bit più a sinistra di v vengono spostate dal lato sinistro:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Quando i bit sono un numero nella rappresentazione del complemento a due, lo spostamento aritmetico a destra ha l'effetto di dividere per una potenza di due. Questo funziona perché il bit più a sinistra è il bit del segno. La divisione per una potenza di due deve mantenere lo stesso segno.
Ulteriori informazioni sugli operatori Bitwise e Bit Shift
>> Signed right shift
>>> Unsigned right shift
La sequenza di bit è data dall'operando di sinistra e il numero di posizioni da spostare dall'operando di destra. L'operatore di spostamento a destra senza segno >>>
sposta uno zero nella posizione più a sinistra ,
mentre la posizione più a sinistra dopo >>
dipende dall'estensione del segno.
In parole semplici, sposta>>>
sempre uno zero nella posizione più a sinistra, mentre >>
cambia in base al segno del numero, ovvero 1 per il numero negativo e 0 per il numero positivo.
Ad esempio, prova con numeri negativi e positivi.
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));
produzione:
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'operatore logico shift destro ( >>> N
) sposta i bit verso destra di N posizioni, scartando il bit di segno e riempiendo gli N di più bit di sinistra con 0. Per esempio:
-1 (in 32-bit): 11111111111111111111111111111111
dopo >>> 1
un'operazione diventa:
2147483647: 01111111111111111111111111111111
L'operatore aritmetico di spostamento a destra ( >> N
) sposta anche i bit a destra di N posizioni, ma conserva il bit di segno e blocca gli N più a sinistra con 1. Per esempio:
-2 (in 32-bit): 11111111111111111111111111111110
dopo >> 1
un'operazione diventa:
-1: 11111111111111111111111111111111