Los operadores a nivel de bits gestionan bits individuales de tipos numéricos enteros:
& — AND a nivel de bits| — OR a nivel de bits^ — XOR a nivel de bits~ — NOT a nivel de bits<< — desplazamiento a la izquierda>> — desplazamiento a la derechaCaracterísticas:
int, unsigned int, etc.).signed) pueden generar un desplazamiento aritmético o lógico al desplazar a la derecha (>>) — depende del compilador.unsigned para evitar la extensión del signo.Ejemplo:
unsigned int flags = 0; flags |= 0x1; // Establecer el bit 0 flags &= ~0x2; // Restablecer el bit 1 if ((flags & 0x4) != 0) { /* ... */ } // Comprobar el bit 2
¿Cuál es la diferencia en la operación de desplazamiento a la derecha (
>>) para los tipossigned intyunsigned int?
Respuesta comúnmente errónea: Se cree que el desplazamiento a la derecha siempre inserta ceros a la izquierda, independientemente de la firma.
Respuesta correcta:
Para el tipo unsigned int, el desplazamiento a la derecha (>>) siempre inserta ceros. Para signed int, se inserta el signo (unos, si el número es negativo) o ceros — depende de la implementación del compilador (arquitectura y reglas del estándar C).
Ejemplo:
signed int a = -8; unsigned int b = (unsigned int)a; printf("%d ", a >> 1); printf("%u ", b >> 1);
En el primer caso, el resultado depende del compilador; en el segundo, siempre será un desplazamiento lógico con ceros.
Historia
En el código de procesamiento de protocolo, las banderas de señal se guardaban en un tipo char. El programador aplicó un desplazamiento de 8 bits (flag << 8), lo que resultó en la pérdida de todos los datos debido a un desbordamiento y las reglas de promoción de tipos — el resultado siempre era cero.
Historia
Lectura de datos de un protocolo de red (big-endian). El uso de operaciones a nivel de bits para combinar bytes no fue acompañado de una conversión a unsigned, lo que a veces llevaba a valores negativos inesperados al leer un campo de una estructura.
Historia
El uso de ~ (NOT a nivel de bits) para restablecer bits en un valor de tipo int (por ejemplo, ~0x80) se interpretaba como 0x7F, pero en realidad resultaba en un número negativo -129, lo que causaba errores en cálculos posteriores y verificaciones lógicas.