2011-09-17 9 views

risposta

13

Divisione e moltiplicazione non sono davvero un impiego di operatori bit-shift. Si tratta di un 'ottimizzazione' obsoleto che alcuni amano applicare.

Sono operazioni bit e completamente necessarie quando si lavora a livello di bit all'interno di un valore intero.

Ad esempio, supponiamo di avere due byte che rappresentano i byte di ordine elevato e di ordine inferiore di un valore senza segno a due byte (16 bit). Di 'che hai bisogno di costruire quel valore. In Java, ovvero:

int high = ...; 
int low = ...; 
int twoByteValue = (high << 8) | low; 

Non si potrebbe altrimenti farlo senza un operatore di turno.

Per rispondere alle tue domande: le usi dove devi usarle! e da nessun'altra parte.

+0

ho sentito, rende più veloci operazioni di divisione/moltiplicazione intera di *,/ – Saravanan

+2

Spostare a sinistra di 1 è più veloce di moltiplicare per 2. Ma il compilatore JIT e il processore lo sanno meglio di te, e dovrebbero farlo automaticamente. In ogni caso, questo non è l'uso * primario dei turni; probabilmente non è nemmeno un buon uso. –

+6

non in java. Nemmeno in C in questi giorni. I compilatori sono abbastanza intelligenti da ottimizzare il tuo codice. È meglio assicurarsi che il codice sia leggibile ed esprimenti ciò che vuole fare piuttosto che cercare di superare in astuzia il compilatore e renderlo illeggibile. Gli operatori di spostamento –

6

L'operatore del cambio viene utilizzato quando si sta eseguendo operazioni logiche bit, al contrario di matematiche operazioni.

È possibile può essere utilizzato per la velocità, essendo significativamente più veloce di divisione/moltiplicazione quando si tratta di operandi che sono potenze di due, ma la chiarezza del codice è solitamente preferita rispetto alla velocità raw.

1

È utile nella costruzione dei valori che sono una combinazione di numeri, in cui i bit sono raggruppate in diversi valori stessi. (Risposta di Sean Owen spiega questo meglio.)

Ad esempio, lavorando con colori che sono:

  • "#AARRGGBB" come stringa base16
  • 0xAAAARRRRGGGGBBBB come intero

Nel suo formato intero , puoi usare shift per ottenere il valore reale di un componente del numero intero come numero utilizzabile.

public static int stringToColor(String s) throws JSExn { 
    // string starts with '#' - parse integer from string 
    try { 
     // used to build up the return value 
     int a, r, g, b; 

     switch (s.length()) { 
     case 4: 
      a = 0xFF000000; 
      r = Integer.parseInt(s.substring(1, 2), 16); 
      r = r << 16 | r << 20; 
      b = Integer.parseInt(s.substring(2, 3), 16); 
      b = b << 8 | b << 12; 
      g = Integer.parseInt(s.substring(3, 4), 16); 
      g = g | g << 4; 
      break; 
     case 5: 
      a = Integer.parseInt(s.substring(1, 2), 16); 
      a = a << 24 | a << 28; 
      r = Integer.parseInt(s.substring(2, 3), 16); 
      r = r << 16 | r << 20; 
      b = Integer.parseInt(s.substring(3, 4), 16); 
      b = b << 8 | b << 12; 
      g = Integer.parseInt(s.substring(4, 5), 16); 
      g = g | g << 4; 
      break; 
     case 7: 
      a = 0xFF000000; 
      r = Integer.parseInt(s.substring(1, 3), 16) << 16; 
      b = Integer.parseInt(s.substring(3, 5), 16) << 8; 
      g = Integer.parseInt(s.substring(5, 7), 16); 
      break; 
     case 9: 
      a = Integer.parseInt(s.substring(1, 3), 16) << 24; 
      r = Integer.parseInt(s.substring(3, 5), 16) << 16; 
      b = Integer.parseInt(s.substring(5, 7), 16) << 8; 
      g = Integer.parseInt(s.substring(7, 9), 16); 
      break; 
     default: 
      throw new JSExn("Not a valid color: '"+s+"'"); 
     } 

     // return our integer ARGB 
     return a | r | b | g; 
} 
0

La riduzione della resistenza si verifica quando un'operazione viene sostituita da un'operazione equivalente che viene eseguita più rapidamente.

  1. sostituzione divisione intera o moltiplicazione per una potenza di 2, con uno spostamento aritmetica o spostamento logico ..
  2. sostituzione intero moltiplicazione per una costante con una combinazione di spostamenti, aggiunge o sottrae.
  3. sostituzione di una divisione intera di una costante con una moltiplicazione, sfruttando l'intervallo limitato di numeri interi della macchina.

Perché è sbagliato?

1. Riduce le prestazioni al crescere del tempo necessario per il calcolo. 2. Le operazioni aritmetiche come la divisione e la moltiplicazione sono più lente. 3. operazioni costose

Vantaggi

  1. migliora le prestazioni.
  2. Calcoli più rapidi.

demerito

  1. leggibilità del codice diminuisce.
0

E 'utile quando avete a che fare con le bandiere, è possibile memorizzare in un solo int variabile le informazioni sui flag attivi, vedi in seguito per favore:

public class DealingWithShiftOperators { 

    public static void main(String[] args) { 

     int active_flags = 10; 

     printActiveFlags(active_flags); 

    } 

    public static void printActiveFlags(int active_flags) { 

     final int TOTAL_FLAGS = 8; 
     final int MAX_VALUE = 1 << TOTAL_FLAGS; 
     final int MIN_VALUE = 1; 

     int current_flag = MAX_VALUE; 

     do { 
      current_flag = current_flag >> 1; 

      if (active_flags - current_flag < 0) { 
       System.out.println(current_flag + ": off"); 
      } else { 
       active_flags = active_flags - current_flag; 
       System.out.println(current_flag + ": on"); 
      } 

     } while (current_flag > MIN_VALUE); 

    } 

} 

L'esempio sopra stampa il seguito all'uscita:

128: off 
64: off 
32: off 
16: off 
8: on 
4: off 
2: on 
1: off 

Come si può vedere, il active_flags sono il numero 2 e il numero 8. Abbiamo conservato le informazioni in una sola variabile, il suo valore è di 10 (8 + 2).

Problemi correlati