2008-11-09 30 views
107

Soy alguien que escribe código solo por diversión y no me he adentrado en él ni en un entorno académico ni profesional, así que cosas como estos operadores bit a bit realmente se me escapan.¿Qué son los operadores bit a bit?

Estaba leyendo un artículo sobre JavaScript, que aparentemente admite operaciones bit a bit. Sigo viendo esta operación mencionada en algunos lugares, y traté de leer para saber qué es exactamente, pero parece que no la tengo. Entonces, ¿qué son? ¡Los ejemplos claros serían geniales! : D

Solo unas pocas preguntas más: ¿cuáles son algunas aplicaciones prácticas de las operaciones bit a bit? ¿Cuándo podrías usarlos?

+0

Soy una persona que escribe el código principalmente sólo por diversión y He escrito un microkernel funcional (pero limitado). En lenguaje ensamblador x86. Por diversión. : D – Artelius

+2

Para más preguntas, es posible que desee agregar una nueva pregunta SO y hacer referencia a esta. Probablemente obtendrás un mejor conjunto de respuestas de esa manera. –

Respuesta

167

Ya que nadie ha abordado el tema de por qué son útiles:

utilizo operaciones bit a bit mucho cuando se trabaja con fl ags. Por ejemplo, si desea pasar una serie de banderas a una operación (por ejemplo, Archivo.Abrir, con el modo Leer y el modo Escritura ambos habilitados), podría pasarlos como un valor único. Esto se logra asignando cada bandera posible su propio bit en un conjunto de bits (byte, corto, int o largo).Por ejemplo:

Read: 00000001 
Write: 00000010 

Así que si quieres pasar leer y escribir, que pasaría (Leer | ESCRITURA) que luego combina los dos en

00000011 

que luego pueden ser descifrados en el otro extremo como:

if ((flag & Read) != 0) { //... 

que comprueba

00000011 & 
00000001 

que devuelve

00000001 

que no es 0, por lo que el indicador no especifica LEER.

Puede usar XOR para alternar varios bits. Lo he usado cuando uso una bandera para especificar entradas direccionales (Arriba, Abajo, Izquierda, Derecha). Por ejemplo, si un sprite se mueve horizontalmente, y lo quiero para dar la vuelta:

 Up: 00000001 
    Down: 00000010 
    Left: 00000100 
    Right: 00001000 
Current: 00000100 

simplemente XOR el valor actual con (IZQUIERDA | DERECHA) que gire a la izquierda y la derecha en, en este caso.

El cambio de bit es útil en varios casos.

x << y 

es lo mismo que

x * 2 y

si es necesario multiplicar rápidamente por una potencia de dos, pero cuidado con el cambio de 1 bit en el bit superior - esto hace que el número sea negativo a menos que no esté firmado. También es útil cuando se trata de diferentes tamaños de datos. Por ejemplo, leyendo un entero de cuatro bytes:

int val = (A << 24) | (B << 16) | (C << 8) | D; 

Suponiendo que A es el byte más significativo y D el menos. Sería terminar como:

A = 01000000 
B = 00000101 
C = 00101011 
D = 11100011 
val = 01000000 00000101 00101011 11100011 

colores son a menudo almacenados de esta manera (con el byte más significativo sea ignorado o se utilizan como Alfa):

A = 255 = 11111111 
R = 21 = 00010101 
G = 255 = 11111111 
B = 0 = 00000000 
Color = 11111111 00010101 11111111 00000000 

Para encontrar los valores de nuevo, simplemente desplazar los bits hacia la derecha hasta que esté en la parte inferior, a continuación, enmascarar los bits de orden superior restantes:

Int Alpha = Color >> 24 
Int Red = Color >> 16 & 0xFF 
Int Green = Color >> 8 & 0xFF 
Int Blue = Color & 0xFF 

0xFF es la misma que 11111111. Así que, esencialmente, para rojo, que estaría haciendo esto:

Color >> 16 = (filled in 00000000 00000000)11111111 00010101 (removed 11111111 00000000) 
00000000 00000000 11111111 00010101 & 
00000000 00000000 00000000 11111111 = 
00000000 00000000 00000000 00010101 (The original value) 
+15

+1 esta es la única buena respuesta dada – TrojanName

+0

¡No obstante, TrojanName no es un comentario a prueba de futuro! –

14

Estos son los operadores de bits, todos soportados en JavaScript:

  • op1 & op2 - El operador AND compara dos bits y genera un resultado de 1 si ambos bits son 1; de lo contrario, devuelve 0.

  • op1 | op2 - El operador OR compara dos bits y genera un resultado de 1 si los bits son complementarios; de otro modo, devuelve 0.

  • op1^ op2 - El operador EXCLUSIVE-OR compara dos bits y devuelve 1 si cualquiera de los bits son 1 y que da 0 si ambos bits son 0 o 1.

  • ~op1 - El operador C OMPLEMENT se usa para invertir todos los bits del operando.

  • op1 << op2 - El operador SHIFT LEFT mueve los bits a la izquierda, descarta el bit más a la izquierda, y asigna el bit más a la derecha un valor de 0. Cada movimiento a la izquierda multiplica efectivamente op1 por 2.

  • op1 >> op2 - The SHIFT RIGHT operador mueve los bits hacia la derecha, descarta el bit de la extrema derecha y asigna el bit más a la izquierda un valor de 0. Cada movimiento hacia la derecha divide efectivamente op1 por la mitad. El bit de signo más a la izquierda se conserva.

  • op1 >>> op2 - The SHIFT RIGHT-ZERO FILL operador mueve los bits a la derecha, descarta el bit más a la derecha, y asigna el bit más a la izquierda un valor de 0. Cada movimiento a la derecha divide efectivamente op1 en medio. El bit de signo más a la izquierda se descarta.

+2

No en todos los idiomas. –

24

Los operadores de bit a bit son operadores que funcionan de a poco a la vez.

y es 1 sólo si tanto de sus entradas son 1.

O es 1 si uno o más de sus entradas son 1.

XOR es 1 sólo si exactamente una de sus entradas son 1.

no es 1 sólo si su entrada es 0.

Estos pueden ser mejor descritos como tablas de verdad. Las posibilidades de entrada están en la parte superior e izquierda, el bit resultante es uno de los cuatro (dos en el caso de NOT, ya que solo tiene una entrada) valores que se muestran en la intersección de las dos entradas.

AND|0 1  OR|0 1 
---+---- ---+---- 
    0|0 0  0|0 1 
    1|0 1  1|1 1 

XOR|0 1  NOT|0 1 
---+---- ---+--- 
    0|0 1  |1 0 
    1|1 0 

Un ejemplo es si solo deseas los 4 bits más bajos de un entero, usted y con 15 (binario 1111) así:

203: 1100 1011 
AND 15: 0000 1111 
------------------ 
IS 11: 0000 1011 
24

Vale la pena señalar que la verdad de un solo bit las tablas enumeradas como otras respuestas funcionan en solo uno o dos bits de entrada a la vez. ¿Qué ocurre cuando se utiliza enteros, tales como:

int x = 5 & 6; 

La respuesta está en la expansión binaria de cada entrada:

5 = 0 0 0 0 0 1 0 1 
& 6 = 0 0 0 0 0 1 1 0 
--------------------- 
     0 0 0 0 0 1 0 0 

Cada par de bits en cada columna se ejecuta a través de la función "AND" para dar el bit de salida correspondiente en la línea inferior. Entonces la respuesta a la expresión anterior es 4. La CPU ha hecho (en este ejemplo) 8 operaciones "Y" separadas en paralelo, una para cada columna.

Menciono esto porque todavía recuerdo haber tenido este "AHA!" momento en que aprendí sobre esto hace muchos años.

+0

Guau, eso tiene mucho más sentido ahora. Parecía mucho más complicado de lo que parece ser. Gracias. No estoy seguro de cuál elegir como la respuesta correcta, ya que hay muchas buenas, y no puedo votar así ... gracias – click

4

Para desglosarlo un poco más, tiene mucho que ver con la representación binaria del valor en cuestión.

 
For example (in decimal): 
x = 8 
y = 1 

would come out to (in binary): 
x = 1000 
y = 0001 

From there, you can do computational operations such as 'and' or 'or'; in this case: 
x | y = 
1000 
0001 | 
------ 
1001 

or...9 in decimal 

Espero que esto ayude.

+0

'|' ¿es una operación de quirófano? – Si8

+0

Por alguna razón, esto tiene más sentido para mí. Todavía no estoy seguro acerca de la 'x | y = 0001 | 'aunque parte – samayo

4

Cuando se menciona el término "bitwise", a veces se aclara que no es un operador "lógico".

Por ejemplo en JavaScript, bitwise operators treat their operands as a sequence of 32 bits (zeros and ones); mientras tanto, logical operators are typically used with Boolean (logical) values pero puede trabajar con tipos no booleanos.

Tome expr1 & & expr2 por ejemplo.

Devuelve expr1 si se puede convertir en falso; de lo contrario, devuelve expr2. Por lo tanto, cuando se usa con valores booleanos, & & devuelve verdadero si ambos operandos son true; de lo contrario, devuelve falso.

a = "Cat" && "Dog"  // t && t returns Dog 
a = 2 && 4  // t && t returns 4 

Como otros han señalado, 2 & 4 es un AND bit a bit, por lo que volverá 0.

Puede copiar el siguiente para Test.html o algo y prueba:

<html> 
<body> 
<script> 
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n" 
     + "2 && 4 = " + (2 && 4) + "\n" 
     + "2 & 4 = " + (2 & 4)); 
</script> 
-5

Me enteré de lo lento que eran los operadores bit a bit de JavaScript. Hice algunas pruebas para my latest blog post y descubrí que eran 40% a 80% más rápidas que la alternativa aritmética en varias pruebas. Quizás solían ser lentos. En los navegadores modernos, los amo.

Tengo un caso en mi código que será más rápido y fácil de leer debido a esto.Mantendré mis ojos abiertos por más.

1

Puede ayudar a pensarlo de esta manera. Esta es la forma en Y (&) funciona:

Básicamente dice son ambos números queridos, por lo que si usted tiene dos números 5 y 3 que será convertida en binario y el equipo va a pensar

  5: 00000101 
     3: 00000011 

son ambos uno: 00000001 0 es falso, 1 es verdadero

Así que el AND de 5 y 3 es uno. El operador OR (|) hace lo mismo, excepto que solo uno de los números debe ser uno para la salida 1, no ambos.

2

En la programación de una computadora digital, una operación en modo bit opera en uno o más patrones de bits o números binarios en el nivel de sus bits individuales. Es una acción rápida, primitiva, directamente soportada por el procesador, y se usa para manipular valores para comparaciones y cálculos. elaboraciones

  • AND bit a bit

  • OR bit a bit

  • bit a bit NO

  • XOR bit a bit

  • etc

elemento de la lista

AND|0 1  OR|0 1 
    ---+----  ---+---- 
     0|0 0   0|0 1 
     1|0 1   1|1 1 

    XOR|0 1  NOT|0 1 
    ---+----  ---+--- 
    0|0 1   |1 0 
    1|1 0 

Ej.

203: 1100 1011 
AND 15: 0000 1111 
------------------ 
    = 11: 0000 1011 

Utilización del operador de bits

  • Los operadores izquierda del turno y desplazamiento a la derecha son equivalentes a la multiplicación y la división por x * 2 y respectivamente.

Eg.

int main() 
{ 
    int x = 19; 
    printf ("x << 1 = %d\n" , x <<1); 
    printf ("x >> 1 = %d\n", x >>1); 
    return 0; 
} 
// Output: 38 9 
  • El operador & se puede utilizar para comprobar rápidamente si un número es par o impar

Ej.

int main() 
{ 
    int x = 19; 
    (x & 1)? printf("Odd"): printf("Even"); 
    return 0; 
} 
// Output: Odd 
  • Rápida mínimo de x e y sin if else DECLARACIÓN

Ej.

int min(int x, int y) 
{ 
    return y^((x^y) & - (x < y)) 
} 
  • decimal a binario conversión

Ej.

#include <stdio.h> 
int main() 
{ 
    int n , c , k ; 
    printf("Enter an integer in decimal number system\n ") ; 
    scanf("%d" , & n); 
    printf("%d in binary number 
    system is: \n " , n) ; 
    for (c = 31; c >= 0 ; c --) 
    { 
     k = n >> c ; 
     if (k & 1) 
       printf("1") ; 
     else 
       printf("0") ; 
     } 
     printf(" \n "); 
     return 0 ; 
} 
  • La puerta XOR es cifrado técnica popular, lástima pues de su complixblity y el uso reare por el programador.
    • operador bit a bit XOR es el operador más útil desde la perspectiva de la entrevista técnica.

bitwuse cambio sólo funciona con + ve número

También existe una amplia gama de uso de la lógica bit a bit

+0

"complixblity and reare ..."? –

Cuestiones relacionadas