¿Alguna vez ha tenido que utilizar el cambio de bits en proyectos reales?

83

¿Alguna vez ha tenido que utilizar el cambio de bits en proyectos de programación reales? La mayoría (si no todos) los lenguajes de alto nivel tienen operadores de turno en ellos, pero ¿cuándo realmente necesitaría usarlos?

Philip Morton
fuente

Respuestas:

58

Todavía escribo código para sistemas que no tienen soporte de punto flotante en hardware. En estos sistemas, necesita cambio de bits para casi toda su aritmética.

También necesitas turnos para generar hashes. Aritmética polinomial (CRC, los códigos Reed-Solomon son las aplicaciones principales) o también utiliza turnos.

Sin embargo, los turnos se utilizan simplemente porque son útiles y expresan exactamente lo que pretendía el escritor. Puede emular todos los cambios de bits con multiplicación si lo desea, pero eso sería más difícil de escribir, menos legible y, a veces, más lento.

Los compiladores detectan casos en los que la multiplicación se puede reducir a un desplazamiento.

Nils Pipenbrinck
fuente
37

Sí, los he usado muchas veces. La manipulación de bits es importante en hardware integrado donde las máscaras de bits son muy comunes. También es importante en la programación de juegos, cuando necesitas hasta el último rendimiento.

Editar: Además, los uso mucho para manipular mapas de bits, por ejemplo, cambiar la profundidad de color o convertir RGB <-> BGR.

MrZebra
fuente
Secundado. Hago mucha programación integrada y el cambio de bits es una operación común.
e.James
Conversiones RGB <-> BGR aquí.
Neil N
25
  • Crear buenos valores de bandera para las enumeraciones (en lugar de escribir manualmente 1, 2, 4 ...)
  • Desempaquetar los datos de los campos de bits (muchos protocolos de red los usan)
  • Travesía de la curva Z
  • Trucos de rendimiento

Y no puedo pensar en muchos casos en los que se estén utilizando. Por lo general, es al revés: hay algún problema específico y resulta que el empleo de operaciones de bits dará los mejores resultados (generalmente en términos de rendimiento, tiempo y / o espacio).

Anónimo
fuente
Es posible que lo necesite para almacenar, por ejemplo, dos shorts en un intcampo eger en el estado de sesión en ASP.net sin la sobrecarga de leer y bloquear la sesión para leer dos valores separados. Además, se guarda la sobrecarga de memoria de almacenar dos valores en la sesión.
David d C e Freitas
15

Un lugar en el que los uso todo el tiempo es cuando transpongo la endianidad de los números enteros para aplicaciones multiplataforma. A veces también resultan útiles (junto con otros operadores de manipulación de bits) al realizar blitting de gráficos 2D.

MattK
fuente
En segundo lugar, escribiendo un convertidor para el juego de caracteres EBCDIC. Desafortunadamente, esto es realmente un trabajo de bajo nivel en un lenguaje de alto nivel, pero es necesario en algunos casos.
Michael Meadows
9

Los he usado algunas veces, pero casi siempre para analizar un formato de archivo binario.

David Grant
fuente
7

Los cambios de bits son rápidos. Fueron implementados en conjuntos de instrucciones de CPU mucho antes que las operaciones de división y módulo. Muchos de nosotros hemos usado cambios de bits para aritmética que es simple en lápiz y papel, pero no está disponible en nuestras CPU.

Por ejemplo:

  • He utilizado cambios de bits para proyectos que implican factorizar grandes compuestos en sus factores primos.
  • También he usado cambios de bits para encontrar el cuadrado y la raíz cúbica de enteros arbitrariamente grandes.
once81
fuente
¿Puede publicar un ejemplo de cómo lo usa para encontrar el cubo o la raíz cuadrada? No veo cómo se puede hacer esto.
Xsmael
5

Sí, todavía es necesario.

Aquí en mi trabajo por ejemplo desarrollamos softwares para la comunicación con PLC a través del puerto serie COMx. Es necesario manejar bits dentro de un byte, usamos shift left / right y operadores lógicos OR, XOR, AND en día a día.

Por ejemplo, supongamos que necesitamos activar el bit 3 (de derecha a izquierda) de un byte:

Es mucho más eficiente hacer:

Byte B;

B := B XOR 4;

En vez de:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

Saludos.

Carlos Eduardo Olivieri
fuente
1
Es posible que desee agregar por qué 4 se relaciona con el bit 3 (de derecha a izquierda)
HCP
1
¿Por qué s [5]? ¿No debería ser S [2]?
IamIC
1
B: = B XOR 4; En este caso, para activar un bit específico, ¿no debería ser solo OR? ¿No se usa XOR para alternar? stackoverflow.com/questions/47981/…
Hari
4

Cuando escribí en lenguaje ensamblador, mi código estaba lleno de cambios de bits y enmascaramiento.

También lo hizo una buena cantidad en C.

No lo he hecho mucho en JavaScript o en lenguajes de servidor.

Probablemente el mejor uso moderno es recorrer una matriz empaquetada de valores booleanos representados como unos y ceros. Siempre solía cambiar a la izquierda y verificar el bit de signo en el ensamblaje, pero en los idiomas de nivel superior se compara con un valor.

Por ejemplo, si tiene 8 bits, marque el bit superior con "if (a> 127) {...}". Luego dejaste shift (o multiplicaste por 2), hiciste un "y" con 127 (o hiciste una resta de 256 si el último bit estaba configurado), y hazlo de nuevo.

Nosredna
fuente
3

Los usé mucho en la compresión / descompresión de imágenes, donde se comprimían los bits en un mapa de bits. Usando http://en.wikipedia.org/wiki/Huffman_coding, las cosas que se comprimen consisten en varios números de bits (no todos están alineados en bytes) y, por lo tanto, debe cambiarlos de bits cuando los codifica o decodifica .

ChrisW
fuente
3

Por ejemplo, en la implementación de métodos criptográficos en lenguajes como C, C ++. Operaciones de archivos binarios, algoritmos de compresión y listas lógicas: la operación bit a bit siempre es buena =)

Anton
fuente
3

El cambio de bits no resuelve problemas de programación de alto nivel, pero a veces tenemos que resolver problemas de nivel inferior, y es conveniente no tener que escribir una biblioteca separada en C para hacerlo. Ahí es cuando más se usa, supongo.

Personalmente lo he usado para escribir un codificador para un convertidor de juego de caracteres EBCDIC .

Michael Meadows
fuente
3

Sí tengo. Como puede sospechar, es más probable que se encuentre en la programación de bajo nivel, por ejemplo, en el desarrollo de controladores de dispositivos. Pero trabajé en un proyecto de C # en el que tuve que desarrollar un servicio web que recibiera datos de dispositivos médicos. Todos los datos binarios que almacenó el dispositivo se codificaron en paquetes SOAP, pero los datos binarios se comprimieron y codificaron. Entonces, para descomprimirlo, tendrías que hacer muchas manipulaciones de bits. Y, además, tendría que hacer muchos cambios de bits para analizar cualquier información útil, por ejemplo, el número de serie del dispositivo es la mitad inferior del segundo byte o algo así. También he visto a algunas personas en el mundo .NET (C #) hacer uso del enmascaramiento de bits y el atributo de bandera, personalmente nunca tuve la necesidad de hacerlo.

WebMatrix
fuente
3

Sí. Tengo que escribir algoritmos de cifrado antes y eso definitivamente los usa.

También son útiles cuando se utilizan números enteros, etc. para realizar un seguimiento de los estados.

Kevin
fuente
3

Al convertir números de formato little endian a big endian y viceversa

Ludwig Wensauer
fuente
3

Trabajo para un fabricante de periféricos de computadora. Me encontré y tuve que implementar código que usa cambios de bits, casi todos los días.

modo interruptor
fuente
3

El cambio de bits se usa mucho para descifrar los protocolos de los juegos en línea. Los protocolos están diseñados para utilizar el menor ancho de banda posible, por lo que en lugar de transmitir la cantidad de jugadores en un servidor, nombres, etc. en int32s, toda la información se empaqueta en la menor cantidad de bytes posible. No es realmente necesario en estos días con la mayoría de las personas que usan banda ancha, pero cuando se diseñaron originalmente, las personas usaban módems de 56k para juegos, por lo que cada bit cuenta.

Los ejemplos más destacados de esto se encuentran en los juegos multijugador de Valve, en particular Counter-Strike, Counter-Strike Source. El protocolo Quake3 también es el mismo, sin embargo, Unreal no es tan delgado.

Aquí hay un ejemplo (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

Por supuesto, si lo ve como un proyecto real o simplemente como un pasatiempo (en C #) depende de usted.

Chris S
fuente
2

Transformada rápida de Fourier: FFT y su técnica Cooley-Tukey requerirán el uso de operaciones de cambio de bits.

LicenciaQ
fuente
¿Estás rodando tus propias rutinas de FFT? tut-tut :) Admito que lo he hecho yo también, genial para comprender profundamente el algoritmo.
Marty
2

Encuentre la potencia más cercana de dos mayores o iguales al número dado:

1 << (int)(ceil(log2(given)))

Necesario para texturizar en hardware que no admite tamaños de textura arbitrarios.

zoul
fuente
1

Sí, los usé en el analizador de flujo de transporte MPEG2-2. Era más fácil y se podía leer mejor.

RvdK
fuente
1

Tuve que escribir un programa para analizar los archivos .ifo en discos DVD. Estos son los archivos que explican cuántos títulos, capítulos, menús, etc. hay en el disco. Están formados por bits empaquetados de todos los tamaños y alineaciones. Sospecho que muchos formatos binarios requieren un cambio de bits similar.

Steve Rowe
fuente
1

He visto el uso de operadores bit a bit cuando se usaron múltiples indicadores como parámetro de propiedad. Por ejemplo, el número 4 = 1 0 0 significa que una de las tres banderas está activada. Esto no es bueno para la API pública, pero puede acelerar las cosas en casos especiales, ya que la verificación de bits es rápida.

Lycha
fuente
1

Cada bitblt-er que escribí no podría haberse completado sin la capacidad de deslizar bits hacia la izquierda y hacia la derecha.

Scott Evernden
fuente
1

Los he usado en juegos para empaquetar un montón de banderas en un solo byte / char para guardar en una tarjeta de datos. Cosas como almacenar el estado de los desbloqueables, etc. No es tanto un requisito hoy en día, pero puede ahorrar trabajo.

xan
fuente
1

Lo uso en un proyecto para un sistema integrado que tiene que leer los datos EDID de un monitor. Algunos datos en un EDID se codifican así:

Byte # 3:
Borrado horizontal - 8 bits inferiores
Byte # 4:
Nibble inferior: Borrado horizontal - 4 bits
superiores Nibble superior: algo más
Tobias Klüpfel
fuente
1

Sí, al realizar una comunicación binaria entre aplicaciones Java y C #, una es el orden de bytes big-endian y la otra es little-endian (no necesariamente en este orden). Creé una clase InputStream que podía leer números con un orden de bytes diferente y usaba el desplazamiento de bytes para funcionar.

A veces, también, cuando desea poner 4 cortos en los 4 bytes de un largo, sería el caso de usar el desplazamiento de bytes. Creo que lo hice hace muchos años ...

Ravi Wallau
fuente
1

Otra cosa muy común es hacer un desplazamiento de 4 bits al extraer el nibble alto de un byte, es decir

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)
hlovdal
fuente
Especialmente cierto si está trabajando directamente con hardware, obteniendo datos directamente de registros con asignaciones de bits arbitrarias.
Chris
0

El desplazamiento de bits también es necesario cuando se comunica con equipos de "nivel inferior", cajas de E / S de ethernet digitales eq o PLC, que generalmente empaquetan valores de entrada / salida inviduales en bytes.

Harriv
fuente
0

Si todo el tiempo. Como estas macros para empaquetar y desempaquetar una coordenada de 3 espacios hacia / desde un entero de 32 bits:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        
caos
fuente
0

Una vez (hace muchos, muchos años) escribí una rutina de salida para un proyecto que creaba hojas de cálculo de Excel usando la estructura de Excel Oper. Este era un formante de archivo binario que requería una gran cantidad de cambios de bits. El siguiente enlace da una idea de la estructura de Oper Safari Books .

Australiano craig
fuente