¿Cuáles son algunos casos de uso en el mundo real de los siguientes operadores bit a bit?
- Y
- XOR
- NO
- O
- Desplazamiento a la izquierda / derecha
language-agnostic
bitwise-operators
Louis Go
fuente
fuente
Respuestas:
Campos de bits (banderas)
Son la forma más eficiente de representar algo cuyo estado está definido por varias propiedades "sí o no". Las ACL son un buen ejemplo; Si tiene 4 permisos discretos (leer, escribir, ejecutar, cambiar la política), es mejor almacenar esto en 1 byte en lugar de desperdiciar 4. Estos pueden asignarse a tipos de enumeración en muchos idiomas para mayor comodidad.
La comunicación a través de puertos / sockets
siempre implica sumas de verificación, paridad, bits de parada, algoritmos de control de flujo, etc., que generalmente dependen de los valores lógicos de bytes individuales en lugar de valores numéricos, ya que el medio solo puede transmitir un bit a un momento.
Compresión, cifrado
Ambos dependen en gran medida de algoritmos bit a bit. Mire el algoritmo de desinflado para ver un ejemplo: todo está en bits, no en bytes.
Máquinas de estado finito
Estoy hablando principalmente del tipo incrustado en alguna pieza de hardware, aunque también se pueden encontrar en el software. Estos son combinatoria en la naturaleza - que podría estar recibiendo, literalmente, "compilado" a un montón de puertas lógicas, así que tienen que ser expresada como
AND
,OR
,NOT
, etc.Gráficos Aquí apenas hay suficiente espacio para acceder a todas las áreas donde se utilizan estos operadores en la programación de gráficos.
XOR
(o^
) es particularmente interesante aquí porque aplicar la misma entrada una segunda vez deshacerá la primera. Las GUI más antiguas solían confiar en esto para resaltar la selección y otras superposiciones, a fin de eliminar la necesidad de redibujos costosos. Todavía son útiles en protocolos de gráficos lentos (es decir, escritorio remoto).Esos fueron solo los primeros ejemplos que se me ocurrieron; esta no es una lista exhaustiva.
fuente
¿Es extraño?
¿Es divisible por dos (par)?
fuente
Aquí hay algunos modismos comunes que tratan con banderas almacenadas como bits individuales.
Establecer la bandera de carga:
Borrar CallerIDMissing flag:
Pruebe si CallerIDMissing y Chargeable están configurados:
fuente
He utilizado operaciones bit a bit en la implementación de un modelo de seguridad para un CMS. Tenía páginas a las que los usuarios podían acceder si se encontraban en grupos apropiados. Un usuario podría estar en varios grupos, por lo que necesitábamos verificar si había una intersección entre los grupos de usuarios y los grupos de páginas. Entonces asignamos a cada grupo un identificador único de potencia de 2, por ejemplo:
O OR estos valores juntos, y almacenamos el valor (como un solo int) con la página. Por ejemplo, si los grupos A y B pueden acceder a una página, almacenamos el valor 3 (que en binario es 00000011) como control de acceso a las páginas. De la misma manera, almacenamos un valor de identificadores de grupo ORed con un usuario para representar en qué grupos se encuentran.
Entonces, para verificar si un usuario determinado puede acceder a una página determinada, solo necesita AND los valores juntos y verificar si el valor no es cero. Esto es muy rápido ya que esta verificación se implementa en una sola instrucción, sin bucles, sin ida y vuelta de la base de datos.
fuente
La programación de bajo nivel es un buen ejemplo. Es posible que, por ejemplo, necesite escribir un bit específico en un registro mapeado en memoria para hacer que una pieza de hardware haga lo que desea:
Además,
htonl()
yhtons()
se implementan utilizando los operadores&
y|
(en máquinas cuya endianness (orden de bytes) no coincide con el orden de la red):fuente
htons()
yhtonl()
son funciones POSIX para cambiar unashort
o unalong
desde el host (h
endianness) a la red (n
orden de bytes).htonl()
por unint
valor de 32 bits ?long
significa 64 bits en muchos idiomas.Los uso para obtener valores RGB (A) de valores de color empaquetados, por ejemplo.
fuente
(a & b) >> c
es más de 5 veces más rápido quea % d / e
(ambas formas de extraer un solo valor de color de un int que representa ARGB). Respectivamente, 6.7s y 35.2s por mil millones de iteraciones.%
no es el operador Módulo, es el operador Restante. Son equivalentes para valores positivos pero difieren con los negativos. Si proporciona las restricciones apropiadas (pasando un enuint
lugar deint
por ejemplo), entonces los dos ejemplos deben tener la misma velocidad.Cuando tengo un montón de banderas booleanas, me gusta almacenarlas todas en un int.
Los saco usando bitwise-AND. Por ejemplo:
etc.
fuente
if (flags.feature_one_is_one) { // turn on feature }
. Está en el estándar ANSI C, por lo que la portabilidad no debería ser un problema.& = Y:
enmascarar bits específicos.
Está definiendo los bits específicos que deberían mostrarse o no mostrarse. 0x0 & x borrará todos los bits en un byte, mientras que 0xFF no cambiará x. 0x0F mostrará los bits en el mordisco inferior.
Conversión:
para convertir variables más cortas en variables más largas con identidad de bits, es necesario ajustar los bits porque -1 en un int es 0xFFFFFFFF mientras que -1 en un largo es 0xFFFFFFFFFFFFFFFF. Para preservar la identidad, aplica una máscara después de la conversión.
| = O
Establecer bits. Los bits se establecerán de forma independiente si ya están configurados. Muchas estructuras de datos (campos de bits) tienen indicadores como IS_HSET = 0, IS_VSET = 1 que se pueden configurar de forma independiente. Para establecer las banderas, aplica IS_HSET | IS_VSET (en C y ensamblaje esto es muy conveniente de leer)
^ = XOR
Encuentra bits que son iguales o diferentes.
~ = NO
Voltear bits.
Se puede demostrar que todas estas posibles operaciones de bits locales pueden implementarse mediante estas operaciones. Entonces, si lo desea, puede implementar una instrucción ADD únicamente mediante operaciones de bit.
Algunos hacks maravillosos:
http://www.ugcs.caltech.edu/~wnoise/base2.html
http://www.jjj.de/bitwizardry/bitwizardrypage.html
fuente
= ~
, no|=
, que es OR.& = AND
: ¿ Por qué querría borrar todos los bits, por qué querría obtener una versión no modificada del byte y qué debo hacer con el mordisco inferior?xor
hacerlo por sí mismo. Se me ocurren bastantes razones por las que quizás quieras extraer el mordisco más bajo. Especialmente si ese mordisco inferior es parte de una estructura de datos y desea usarlo como una máscara oOR
con otra estructura.El cifrado es todas las operaciones bit a bit.
fuente
Puede usarlos como una forma rápida y sucia de hacer hash de datos.
fuente
Acabo de usar bitwise-XOR (
^
) hace unos tres minutos para calcular una suma de verificación para la comunicación en serie con un PLC ...fuente
Bitwise & se usa para enmascarar / extraer una cierta parte de un byte.
Variable de 1 byte
Especialmente el operador de turno (<< >>) se usa a menudo para los cálculos.
fuente
Este es un ejemplo para leer colores de una imagen de mapa de bits en formato byte
Espero que estos pequeños ejemplos ayuden ...
fuente
En el mundo abstracto del lenguaje moderno de hoy, no demasiados. File IO es fácil de recordar, aunque está ejerciendo operaciones bit a bit en algo ya implementado y no está implementando algo que utiliza operaciones bit a bit. Aún así, como un ejemplo sencillo, este código demuestra la eliminación del atributo de solo lectura en un archivo (para que pueda usarse con un nuevo FileStream que especifique FileMode.Create) en c #:
En cuanto a las implementaciones personalizadas, aquí hay un ejemplo reciente: creé un "centro de mensajes" para enviar mensajes seguros de una instalación de nuestra aplicación distribuida a otra. Básicamente, es análogo al correo electrónico, completo con Bandeja de entrada, Bandeja de salida, Enviado, etc., pero también tiene entrega garantizada con recibos de lectura, por lo que hay subcarpetas adicionales más allá de "bandeja de entrada" y "enviado". Lo que esto significó fue un requisito para mí para definir genéricamente qué está "en la bandeja de entrada" o qué está "en la carpeta enviada". De la carpeta enviada, necesito saber qué se lee y qué no se lee. De lo que no se ha leído, necesito saber qué se recibe y qué no. Utilizo esta información para crear una cláusula where dinámica que filtre una fuente de datos local y muestre la información adecuada.
Así es como se ensambla la enumeración:
¿Ves lo que hace esto? Al llamar (&) con el valor de enumeración "Inbox", InboundMemos, sé que InboundMemosForMyOrders está en la bandeja de entrada.
Aquí hay una versión resumida del método que crea y devuelve el filtro que define una vista para la carpeta seleccionada actualmente:
Extremadamente simple, pero una implementación ordenada a un nivel de abstracción que generalmente no requiere operaciones bit a bit.
fuente
La codificación Base64 es un ejemplo. La codificación Base64 se utiliza para representar datos binarios como caracteres imprimibles para enviar a través de sistemas de correo electrónico (y otros fines). La codificación Base64 convierte una serie de bytes de 8 bits en índices de búsqueda de caracteres de 6 bits. Las operaciones de bit, desplazamiento, y 'o' no-son son muy útiles para implementar las operaciones de bit necesarias para la codificación y decodificación Base64.
Por supuesto, esto es solo 1 de innumerables ejemplos.
fuente
Me sorprende que nadie haya elegido la respuesta obvia para la era de Internet. Cálculo de direcciones de red válidas para una subred.
http://www.topwebhosts.org/tools/netmask.php
fuente
Por lo general, las operaciones bit a bit son más rápidas que multiplicar / dividir. Entonces, si necesita multiplicar una variable x por decir 9, hará lo
x<<3 + x
que sería unos ciclos más rápido quex*9
. Si este código está dentro de un ISR, ahorrará tiempo de respuesta.Del mismo modo, si desea utilizar una matriz como una cola circular, sería más rápido (y más elegante) manejar cheques envolventes con operaciones de bits sabios. (el tamaño de su matriz debe ser una potencia de 2). Por ejemplo: puedes usar en
tail = ((tail & MASK) + 1)
lugar detail = ((tail +1) < size) ? tail+1 : 0
, si desea insertar / eliminar.Además, si desea que un indicador de error mantenga juntos varios códigos de error, cada bit puede contener un valor separado. Puede Y con cada código de error individual como un cheque. Esto se usa en los códigos de error de Unix.
También un mapa de bits de n bits puede ser una estructura de datos realmente genial y compacta. Si desea asignar un grupo de recursos de tamaño n, podemos usar n bits para representar el estado actual.
fuente
Nadie parece haber mencionado matemáticas de punto fijo.
(Sí, soy viejo, ¿vale?)
fuente
¿Es un número
x
una potencia de 2? (Útil, por ejemplo, en algoritmos en los que se incrementa un contador, y una acción se debe tomar solo logarítmicamente varias veces)¿Cuál es el bit más alto de un entero
x
? (Esto, por ejemplo, se puede utilizar para encontrar la potencia mínima de 2 que es mayor quex
)¿Cuál es el
1
bit más bajo de un enterox
? (Ayuda a encontrar el número de veces divisible por 2.)fuente
x & -x
.Los operadores a nivel de bits son útiles para la formación de bucles de matrices cuya longitud es una potencia de 2. Como muchas personas mencionaron, los operadores a nivel de bits son extremadamente útiles y se utilizan en Banderas , Gráficos , Redes , Cifrado . No solo eso, sino que son extremadamente rápidos. Mi uso favorito personal es hacer un loop de una matriz sin condicionales . Suponga que tiene una matriz basada en índice cero (por ejemplo, el índice del primer elemento es 0) y necesita hacer un bucle indefinidamente. Por indefinidamente me refiero a ir del primer elemento al último y volver al primero. Una forma de implementar esto es:
Este es el enfoque más simple, si desea evitar la declaración if , puede usar el enfoque de módulo de la siguiente manera:
El lado negativo de estos dos métodos es que el operador de módulo es costoso, ya que busca un resto después de la división de enteros. Y el primer método ejecuta una instrucción if en cada iteración. Con el operador bit a bit, sin embargo, si la longitud de su matriz es una potencia de 2, puede generar fácilmente una secuencia como
0 .. length - 1
utilizando el&
operador (bit a bit y) como tali & length
. Entonces, sabiendo esto, el código de arriba se convierteAsí es como funciona. En formato binario , cada número que es potencia de 2 restada por 1 se expresa solo con unos. Por ejemplo, 3 en binario es
11
, 7 es111
, 15 es1111
y así sucesivamente, se entiende la idea. Ahora, ¿qué sucede si&
cualquier número contra un número que consta solo de unos en binario? Digamos que hacemos esto:Si
num
es menor o igual a 7, el resultado seránum
porque cada bit&
con 1 es él mismo. Sinum
es mayor que 7, durante la&
operación, la computadora considerará los ceros iniciales de 7, que por supuesto permanecerán como ceros después de la&
operación, solo permanecerá la parte final. Como en el caso de9 & 7
en binario se verá comoel resultado será 0001, que es 1 en decimal y se dirige al segundo elemento en la matriz.
fuente
Los uso para opciones de selección múltiple, de esta manera solo almaceno un valor en lugar de 10 o más
fuente
También puede ser útil en un modelo relacional SQL, supongamos que tiene las siguientes tablas: BlogEntry, BlogCategory
Tradicionalmente, podría crear una relación nn entre ellos utilizando una tabla BlogEntryCategory o cuando no hay tantos registros BlogCategory, podría usar un valor en BlogEntry para vincular a múltiples registros BlogCategory al igual que lo haría con enumeraciones marcadas, en la mayoría de RDBMS también hay un operador muy rápido para seleccionar en esa columna 'marcada' ...
fuente
Cuando solo desea cambiar algunos bits de las salidas de un microcontrolador, pero el registro para escribir es un byte, debe hacer algo como esto (pseudocódigo):
Por supuesto, muchos microcontroladores le permiten cambiar cada bit individualmente ...
fuente
Si alguna vez desea calcular su número de mod (%) una cierta potencia de 2, puede usar
yourNumber & 2^N-1
, que en este caso es el mismo queyourNumber % 2^N
.Esto probablemente solo sea útil como una alternativa a la operación de módulo con un dividendo muy grande que es 2 ^ N ... Pero incluso entonces su aumento de velocidad sobre la operación de módulo es insignificante en mi prueba en .NET 2.0. Sospecho que los compiladores modernos ya realizan optimizaciones como esta. Alguien sabe más sobre esto?
fuente
%
es la operación Remainder, tratan los negativos de manera diferente. Sin embargo, si pasauint
a%
, el compilador de C # realmente producirá código de máquina usando bit a bit Y cuando el segundo argumento es una potencia conocida de dos.Los he visto utilizados en sistemas de control de acceso basados en roles.
fuente
Hay un uso del mundo real en mi pregunta aquí:
¿Responde solo a la primera notificación WM_KEYDOWN?
Cuando se consume un mensaje WM_KEYDOWN en Windows C, el bit 30 especifica el estado de la clave anterior. El valor es 1 si la tecla está abajo antes de enviar el mensaje, o es cero si la tecla está arriba
fuente
Se utilizan principalmente para operaciones bit a bit (sorpresa). Aquí hay algunos ejemplos del mundo real que se encuentran en la base de código PHP.
Codificación de caracteres:
Estructuras de datos:
Controladores de base de datos:
Implementación del compilador:
fuente
Cada vez que comencé a programar en C, entendí las tablas de verdad y todo eso, pero no todo hizo clic en cómo usarlo realmente hasta que leí este artículo http://www.gamedev.net/reference/articles/article1563.asp (que da ejemplos de la vida real)
fuente
x == 1
yy == 2
, luego sex || y
evalúa a 1, y sex | y
evalúa a 0. Tampoco veo por quéx^true
es superior de!x
ninguna manera. Es más mecanografiado, menos idiomático, y six
no esbool
así, no es confiable.x^true
es superior!x
es quesome->complicated().member->lookup ^= true;
no hay versiones de asignación compuesta de operadores unarios.No creo que esto cuente como bit a bit, pero Ruby's Array define las operaciones de conjunto a través de los operadores enteros normales a nivel de bit. Por lo tanto
[1,2,4] & [1,2,3] # => [1,2]
. Del mismo modo paraa ^ b #=> set difference
ya | b #=> union
.fuente
La solución lineal de Tower Of Hanoi utiliza operaciones bit a bit para resolver el problema.
La explicación de esta solución se puede encontrar aquí.
fuente