Es una especie de compresión simple en la que utiliza una variable numérica para almacenar muchos estados booleanos / binarios, utilizando la duplicación y el hecho de que cada número de duplicación es 1 + la suma de todos los anteriores.
Estoy seguro de que debe ser una técnica antigua y bien conocida, me gustaría saber cómo se llama para referirme a ella correctamente. Hice varias búsquedas en todas las formas en que puedo pensar para describirlo, pero no encontré nada más allá de algunos artículos de blog en los que los autores del artículo parecen haberlo descubierto ellos mismos y tampoco saben cómo llamarlo ( ejemplo 1 , ejemplo 2 ).
Por ejemplo, aquí hay una implementación muy simple destinada a ilustrar el concepto:
packStatesIntoNumber () {
let num = 0
if (this.stateA) num += 1
if (this.stateB) num += 2
if (this.stateC) num += 4
if (this.stateD) num += 8
if (this.stateE) num += 16
if (this.stateF) num += 32
return num
}
unpackStatesFromNumber (num) {
assert(num < 64)
this.stateF = num >= 32; if (this.stateF) num -= 32
this.stateE = num >= 16; if (this.stateE) num -= 16
this.stateD = num >= 8; if (this.stateD) num -= 8
this.stateC = num >= 4; if (this.stateC) num -= 4
this.stateB = num >= 2; if (this.stateB) num -= 2
this.stateA = num >= 1; if (this.stateA) num -= 1
}
También podría usar operadores bit a bit, análisis de números de base 2, enumeraciones ... Hay muchas maneras más eficientes de implementarlo, estoy interesado en el nombre del enfoque en general.
fuente
enums
, y pueden tener unFlags
atributo. Podrían hacer que su código sea mucho más simple.bool
generalmente se almacena internamente como un entero de 32 bits. Como tal, el embalaje puede marcar la diferencia de un factor de 32. Eso es realmente mucho. Quiero decir, los programadores siempre estamos listos para tirar la mitad de nuestros recursos, pero generalmente soy reacio a tirar el 97% de ellos. Tales factores de desperdicio pueden hacer fácilmente la diferencia entre poder ejecutar casos de uso importantes y quedarse sin memoria.Respuestas:
Se conoce comúnmente como un campo de bits , y otro término que a menudo escuchará es máscaras de bits , que se utilizan para obtener o establecer valores de bits individuales o todo el campo de bits a la vez.
Muchos lenguajes de programación tienen estructuras auxiliares para ayudar con esto. Como @BernhardHiller señala en los comentarios, C # tiene enumeraciones con banderas ; Java tiene la clase EnumSet .
fuente
BitArray
, lo que permite almacenar una cantidad arbitraria de bits e indexarlos (mientras que las banderas están limitadas a un tipo entero y están destinadas a ser utilizadas como máscaras).Extraño, hay muchos términos diferentes aquí, pero no veo el que me vino a la mente de inmediato (¡y está en el título de su pregunta!) - Bit Packing es lo que siempre he escuchado llamarlo.
Pensé que esto era realmente obvio, pero extrañamente, cuando lo busco en Google, este parece ser un término que se usa ampliamente pero no está definido oficialmente (Wikipedia parece redirigir al campo de bits, que es una forma de empaquetar bits, pero no un nombre para el proceso). La búsqueda de la definición parece conducir a esta página:
http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101
Lo que no es bueno para fines SO, pero es la mejor definición / descripción que puedo encontrar, incluida esta breve descripción: "El empaquetado de bits es un concepto simple: use la menor cantidad posible para almacenar una pieza de datos".
fuente
char
matriz al poner doschar
s en unoint
.Hay muchos términos diferentes utilizados para describir esto.
Lo más común es que los bits se denominen "banderas de bits" o "campos de bits".
(Sin embargo, vale la pena señalar que los "campos de bits" a veces se refieren a una característica específica de los lenguajes C y C ++, que está relacionada pero no es exactamente la misma).
El entero en sí mismo se conoce como "matriz de bits", "conjunto de bits" o "vector de bits", según los usos y las circunstancias.
De cualquier manera, la extracción de los bits del conjunto de bits / vector / matriz se realiza mediante desplazamiento y enmascaramiento.
(es decir, usando una máscara de bits ).
Para algunos ejemplos de cada término en uso activo:
std::bitset
BitSet
BitArray
bitvector
,bitarray
ybitset
bitarray
proyecto y unBitVector
proyectoNo es realmente pertinente para la pregunta, pero me gustaría decir: por favor, no use la suma y la resta para establecer y borrar bits, ya que esos métodos son propensos a errores.
(es decir, si lo hace
num += 1
dos veces, el resultado es equivalente anum += 2
).En su lugar, prefiere utilizar las operaciones bit a bit apropiadas, si su idioma elegido las proporciona:
fuente
this.stateF = (num & 32) ? true : false
, etc. No es necesario mutarnum
mientras extrae los valores.+
y-
. Ahora me he vuelto mejor y he usado en!= 0
lugar de un ternario, lo que creo que es más conciso y aún así es explícito.