Differenza tra >>> e >>


Risposte:


408

>>è 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.


8
Mentre sono d'accordo e apprezzo il fatto che i turni aritmetici possano essere utilizzati per moltiplicare i numeri firmati 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?
Ziggy,

11
Perché dici che una stringa di bit non è un numero? Diresti che una sequenza di cifre decimali non è un numero?
danben,

4
@danben Discutere se è o meno un numero ha senso solo se lo si collega a un contesto. Se Internet è solo elettricità, sono d'accordo che una stringa è solo un numero.
bvdb,

1
@danben ma in realtà, penso che ciò a cui Ziggy si riferiva veramente (imho), è che a Stringpotrebbe anche essere considerato un char[]. Non sta dicendo che a charnon è un numero; sta solo dicendo che è un numero senza segno . Penso che sia lì che ha perso.
bvdb,

5
@Ziggy ha ragione: non tutte le stringhe di bit sono un numero e non ogni sequenza di cifre decimali è un numero. Ad esempio: numeri di telefono, codici postali (in molti paesi) ecc. Sono stringhe di cifre decimali, ma non ha senso aggiungerle, sottrarle o moltiplicarle, quindi non sono numeri. Capita di essere stringhe di cifre decimali, ma dovrebbero essere trattate come stringhe di caratteri. (I codici postali in Canada e Regno Unito contengono lettere e cifre.)
jcsahnwaldt dice GoFundMonica

102

>>>è turno senza segno; inserirà 0. >>è firmato ed estenderà il bit di segno.

JLS 15.19 Operatori a turni

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 bit nspostate sa destra con estensione del segno .

Il valore di n>>>sè posizioni di bit nspostate sa 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.

Domande correlate


Senza i tuoi esempi, non lo capirei.
5

47

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.


12
puoi spiegare con un esempio
Kasun Siyambalapitiya il

1
Penso anche che dovresti fare un esempio.
byxor,

Suppongo che >>>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 32turni, è tornato a 7. L'unico modo in cui ciò potrebbe avere senso è che per ogni numero spostato, entra in un "cerchio esterno". Dopo i 32turni, è tornato in qualche modo alla sua posizione, ma ovviamente non ha ancora senso. Cosa sta succedendo?
Ian Limarta,

@IanLimarta Non è così? Ottengo solo 0. ( for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));) Se intendi perché >>32restituisce il valore originale, vedi questo .
Moira,

Mi dispiace. Intendevo perché "7 >>> 32 = 7".
Ian Limarta,

40

Lo spostamento logico a destra ( v >>> n) restituisce un valore in cui i bit in vsono stati spostati a destra dalle nposizioni 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 vsono stati spostati a destra dalle nposizioni 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.


38

>>>inserirà sempre uno 0 nel bit più a sinistra, mentre >>inserirà uno o uno 0 a seconda di quale sia il suo segno.


10

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

Grazie. Voglio solo aggiungere un commento per fare riferimento alla rappresentazione dei bit per Integer.MAX_VALUE, Integer.MIN_VALUE, -1, 0, 1 . ad es .: 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
Andy Dong

6

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 >>> 1un'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 >> 1un'operazione diventa:

-1: 11111111111111111111111111111111
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.