¿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?
¿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?
Respuestas:
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.
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.
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).
short
s en un int
campo 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.
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.
Los he usado algunas veces, pero casi siempre para analizar un formato de archivo binario.
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:
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.
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.
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 .
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 .
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.
Al convertir números de formato little endian a big endian y viceversa
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.
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.
Transformada rápida de Fourier: FFT y su técnica Cooley-Tukey requerirán el uso de operaciones de cambio de bits.
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.
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.
Cada bitblt-er que escribí no podría haberse completado sin la capacidad de deslizar bits hacia la izquierda y hacia la derecha.
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
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 ...
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)
Sí, el cambio de bits se utiliza en software integrado de bajo nivel todo el tiempo. También se puede utilizar como un truco casi mágico para realizar operaciones matemáticas extremadamente rápidas, eche un vistazo a
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
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))
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 .