2011-09-17 11 views

Respuesta

13

división y multiplicación no son realmente un uso de los operadores de bits de desplazamiento. Son una "optimización" obsoleta que a algunos les gusta aplicar.

Son operaciones de bits, y completamente necesarias cuando se trabaja en el nivel de bits dentro de un valor entero.

Por ejemplo, supongamos que tengo dos bytes que son los bytes de orden superior y de orden inferior de un valor sin signo de dos bytes (16 bits). Digamos que necesita construir ese valor. En Java, eso es:

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

No podría hacer esto sin un operador de desplazamiento.

Para responder a sus preguntas: ¡las usa donde las necesita! y en ninguna otra parte

+0

me enteré, hace operaciones más rápidas de división/multiplicación de enteros que *,/ – Saravanan

+2

Cambiar a la izquierda por 1 es más rápido que multiplicar por 2. Pero su compilador JIT y su procesador lo saben mejor que usted, y deberían hacerlo automáticamente. En cualquier caso, este no es el uso * primario * de los turnos; es discutible que ni siquiera sea un buen uso. –

+6

no en java. Ni siquiera en C en estos días. Los compiladores son lo suficientemente inteligentes como para optimizar su código. Lo mejor es asegurarse de que su código sea legible y exprese lo que quiere hacer en lugar de intentar superar al compilador y hacerlo ilegible. –

6

El operador de desplazamiento se utiliza cuando se está realizando operaciones lógicas los pedacitos, en contraposición a matemáticos operaciones.

Se puede ser utilizado para la velocidad, siendo significativamente más rápido que la división/multiplicación cuando se trata de operandos que son potencias de dos, pero la claridad del código es generalmente preferible a la velocidad pura.

1

Es útil en la construcción de valores que son una combinación de números, donde los bits se agrupan como valores diferentes a sí mismos. (Respuesta de Sean Owen explica esto mejor.)

Por ejemplo, el trabajo con los colores que son:

  • "#AARRGGBB" como una cadena Base16
  • 0xAAAARRRRGGGGBBBB como un entero

En su formato entero , puede usar shift para obtener el valor real de un componente del número entero como un número utilizable.

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

reducción de la fuerza se produce cuando una operación se sustituye por una operación equivalente que ejecuta más rápido.

  1. sustitución de división de enteros o multiplicación por una potencia de 2 con un desplazamiento aritmético o desplazamiento lógico ..
  2. sustitución de multiplicación número entero por una constante con una combinación de desplazamientos, suma o resta.
  3. reemplazando la división de enteros por una constante con una multiplicación, aprovechando el rango limitado de enteros de la máquina.

¿Por qué es esto incorrecto?

1.Reduce el rendimiento a medida que aumenta el tiempo necesario para el cálculo. 2. Las operaciones aritméticas como la división y la multiplicación son más lentas. 3. operaciones costosas

Beneficios

  1. mejora el rendimiento.
  2. Cálculos más rápidos.

Demérito

  1. legibilidad del código disminuye.
0

Es útil cuando se trabaja con banderas, podría almacenar en un solo int variable de la información acerca de las marcas activas, ver siguiente por favor:

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); 

    } 

} 

el ejemplo anterior se imprime el seguimiento a la salida:

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

Como se puede ver, el active_flags son el número 2 y número 8. Nos guardaron esa información en una sola variable, su valor es de 10 (8 + 2).

Cuestiones relacionadas