En informática , un desplazamiento lógico es una operación bit a bit que desplaza todos los bits de su operando. Las dos variantes básicas son el desplazamiento lógico a la izquierda y el desplazamiento lógico a la derecha . Esto se modula además por el número de posiciones de bit que se desplazará un valor dado, como el desplazamiento a la izquierda en 1 o el desplazamiento a la derecha en n . A diferencia de un desplazamiento aritmético , un desplazamiento lógico no conserva el bit de signo de un número ni distingue el exponente de un número de su significando (mantisa); cada bit del operando simplemente se mueve un número determinado de posiciones de bit, y las posiciones de bit vacantes se llenan, generalmente con ceros y posiblemente unos (en contraste con un desplazamiento circular ).
Un desplazamiento lógico se utiliza a menudo cuando su operando se trata como una secuencia de bits en lugar de como un número.
Los desplazamientos lógicos pueden ser útiles como formas eficientes de realizar la multiplicación o división de números enteros sin signo por potencias de dos. Desplazar n bits hacia la izquierda en un número binario con o sin signo tiene el efecto de multiplicarlo por 2 n . Desplazar n bits hacia la derecha en un número binario sin signo tiene el efecto de dividirlo por 2 n (redondeando hacia 0).
El desplazamiento lógico a la derecha difiere del desplazamiento aritmético a la derecha. Por lo tanto, muchos lenguajes tienen operadores diferentes para ellos. Por ejemplo, en Java y JavaScript , el operador de desplazamiento lógico a la derecha es >>> , pero el operador de desplazamiento aritmético a la derecha es >> . (Java tiene solo un operador de desplazamiento a la izquierda ( << ), porque el desplazamiento a la izquierda a través de la lógica y la aritmética tiene el mismo efecto).
Sin embargo, los lenguajes de programación C , C++ y Go tienen un solo operador de desplazamiento a la derecha, >> . La mayoría de las implementaciones de C y C++, y Go, eligen qué desplazamiento a la derecha realizar según el tipo de entero que se esté desplazando: los enteros con signo se desplazan utilizando el desplazamiento aritmético y los enteros sin signo se desplazan utilizando el desplazamiento lógico. En particular, C++ utiliza sus operadores de desplazamiento lógico como parte de la sintaxis de sus funciones de entrada y salida, llamadas "cin" y "cout" respectivamente.
Todas las normas de C actualmente relevantes (ISO/IEC 9899:1999 a 2011) dejan un vacío de definición para los casos en los que el número de desplazamientos es igual o mayor que el número de bits en los operandos de manera que el resultado no está definido. Esto ayuda a permitir que los compiladores de C emitan código eficiente para varias plataformas al permitir el uso directo de las instrucciones de desplazamiento nativas que tienen un comportamiento diferente. Por ejemplo, shift-left-word en PowerPC elige el comportamiento más intuitivo donde el desplazamiento por el ancho de bit o superior da cero, [6] mientras que SHL en x86 elige enmascarar la cantidad de desplazamiento a los bits inferiores para reducir el tiempo máximo de ejecución de las instrucciones , y como tal, un desplazamiento por el ancho de bit no cambia el valor. [7]
Algunos lenguajes, como .NET Framework y LLVM , también dejan sin especificar (.NET) [8] o sin definir (LLVM) el desplazamiento por el ancho de bits y superior. [9] Otros optan por especificar el comportamiento de sus plataformas de destino más comunes, como C#, que especifica el comportamiento x86. [10]
Si la secuencia de bits 0001 0111 (decimal 23) se desplaza lógicamente una posición de bit, entonces:
Nota: MSB = bit más significativo, LSB = bit menos significativo