HOWTO · Csharp
Usar máscara de bits en C#
En este artículo, aprenderemos a usar la máscara de bits en C#.
En esta página
Una máscara de bits es un entero cuyos bits individuales representan indicadores independientes. Por ejemplo, un valor de permisos puede almacenar en un solo número los permisos de lectura, escritura y ejecución. Los operadores bit a bit de C# permiten comprobar, extraer, activar, desactivar, alternar, invertir y desplazar esos bits. Usa máscaras con nombre para indicar qué indicador afecta cada operación.
Comprender las máscaras de bits y los operadores bit a bit
Cada bit vale 0 o 1. Los operadores comparan los bits correspondientes: AND (&) produce 1 solo cuando ambas entradas son 1; OR (|) produce 1 cuando cualquiera de las entradas es 1; XOR (^) produce 1 cuando las entradas son distintas; y NOT (~) invierte todos los bits de su operando entero. Los operadores de desplazamiento (<< y >>) mueven los bits el número de posiciones indicado.
| Operación | Significado para cada bit |
|---|---|
x & y |
Conserva un bit solo si está activado en ambos valores. |
| `x | y` |
x ^ y |
Activa un bit si está activado en exactamente uno de los valores. |
~x |
Invierte todos los bits de la representación entera. |
Una máscara es un valor que tiene 1 en las posiciones de interés y 0 en las demás. Es preferible usar constantes con nombre, como Read = 1 y Write = 2; estos valores seleccionan posiciones de bit distintas.
Comprobar y extraer bits con &
Para comprobar un indicador, aplica AND al valor y su máscara. El indicador está presente si el resultado no es cero: if ((permissions & Read) != 0). Esto funciona porque la máscara pone a cero todas las demás posiciones. Para extraer varios bits seleccionados, usa una máscara que incluya esas posiciones; el resultado conserva únicamente los bits seleccionados. Por ejemplo, permissions & (Read | Write) extrae juntos los indicadores de lectura y escritura.
Activar bits con |
Aplica OR a un valor y una máscara de indicador para activar esos bits y conservar los demás. La asignación compuesta permissions |= Write es una forma abreviada de asignar permissions | Write de nuevo a permissions. Si el indicador ya está activado, seguirá estándolo; por eso esta operación sirve para asegurarse de que un indicador quede habilitado.
Alternar bits con ^
XOR con una máscara invierte solo las posiciones en las que la máscara tiene 1: permissions ^= Execute. Un bit activado pasa a estar desactivado y uno desactivado pasa a estar activado. Esto resulta útil para alternar un indicador de forma deliberada, pero no sirve para asegurarse de que esté activado de manera idempotente: aplicar la operación dos veces restaura el valor original.
Invertir bits con ~
NOT invierte todos los bits del tipo entero, incluidas las posiciones que no forman parte de los indicadores que usa la aplicación. Para desactivar un indicador conocido, combina AND con la máscara complementada: permissions &= ~Write. Las demás posiciones de los indicadores permanecen sin cambios. Si necesitas mostrar el valor invertido como una cadena de bits de ancho fijo, aplica primero una máscara de ese ancho; el resultado numérico de ~value no se limita por sí mismo a los indicadores visibles.
Desplazar bits con << y >>
Un desplazamiento a la izquierda mueve los bits hacia posiciones de mayor valor. Para valores no negativos cuyo resultado desplazado cabe en el tipo, value << count equivale a multiplicar por una potencia de dos. Un desplazamiento a la derecha mueve los bits hacia posiciones de menor valor; para valores no negativos, descarta los bits de menor peso desplazados. En valores negativos con signo, el desplazamiento a la derecha de C# conserva el bit de signo, así que no describas todos los desplazamientos a la derecha como si insertaran ceros. Usa un tipo sin signo cuando necesites un desplazamiento lógico a la derecha y elige una cantidad de desplazamiento adecuada para el tipo entero.
Los desplazamientos también permiten construir máscaras de forma concisa: 1 << 0, 1 << 1 y 1 << 2 seleccionan posiciones de bit consecutivas para cantidades pequeñas y no negativas. En el código de una aplicación, las constantes con nombre suelen ser más fáciles de leer.
Combinar indicadores en un ejemplo práctico
Este programa empieza sin permisos, activa los indicadores de lectura y escritura, los comprueba y extrae, desactiva escritura y, después, alterna ejecución. Cada valor impreso describe el estado tras la operación correspondiente. El ejemplo incluye un punto de entrada Main completo y usa máscaras decimales.
Ejecuta este ejemplo. Los identificadores del código y la salida booleana permanecen en inglés.
using System;
class Program
{
static void Main()
{
const int Read = 1;
const int Write = 2;
const int Execute = 4;
int permissions = 0;
permissions |= Read | Write;
Console.WriteLine((permissions & Read) != 0);
Console.WriteLine(permissions & (Read | Write));
permissions &= ~Write;
permissions ^= Execute;
Console.WriteLine(permissions);
}
}
La primera operación activa dos indicadores con OR. La comprobación imprime si Read está presente y la extracción muestra los bits numéricos seleccionados. La operación &= ~Write desactiva únicamente el bit de escritura; después, XOR alterna el indicador de ejecución. Mantén las máscaras y los valores almacenados en tipos enteros compatibles y usa indicadores con nombre para que las posiciones previstas queden claras.