¿Cuál es el nombre para almacenar / empaquetar muchos estados booleanos en un solo número?

53

Es una especie de compresión simple en la que se usa 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 todas las anteriores.

Estoy seguro de que debe ser una técnica antigua y bien conocida, me gustaría saber cómo se llama para referirse a ella correctamente. He hecho varias búsquedas en todas las formas que se me ocurren para describirlo, pero no he encontrado nada más que en algunos artículos de blogs donde los autores del artículo parecen haberlo descubierto por sí mismos y tampoco saben cómo llamarlo ( example 1 , example 2 ).

Por ejemplo, aquí hay una implementación muy simple que pretende 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 puede usar operadores bitwise, análisis de números de base 2, enumeraciones ... Hay muchas formas más eficientes de implementarlo, estoy interesado en el nombre del enfoque de manera más general.

    
pregunta user568458 15.10.2018 - 10:43

3 respuestas

105

Se suele denominar campo de bits , y otro término que escuchará a menudo es bit masks , que se usan 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 enums con flags ; Java tiene la clase EnumSet .

    
respondido por el Glorfindel 15.10.2018 - 11:16
20

Extraño, hay un montón de términos diferentes aquí, pero no veo el que me vino a la mente de inmediato (¡y está en el título de tu pregunta!) - Bit Packing es lo que siempre he escuchado denominar.

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á oficialmente definido (Wikipedia parece redirigir al campo de bits, que es una forma de empaquetar los bits, pero no una nombre para el proceso). La búsqueda de la definición parece llevar a esta página:

enlace

Lo que no es bueno para 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 de bits posible para almacenar una parte de los datos".

    
respondido por el Bill K 15.10.2018 - 18:13
13

Hay muchos términos diferentes utilizados para describir esto.

En general, los bits se denominan "indicadores de bit" o "campos de bit".
(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í se conoce como "matriz de bits", "conjunto de bits" o "vector de bits", dependiendo de los usos y circunstancias.

De cualquier manera, la extracción de los bits del conjunto de bits / vector / matriz se realiza mediante el desplazamiento y el enmascaramiento.
(es decir, utilizando una máscara de bits .)

Para algunos ejemplos de cada término en uso activo:

No es realmente pertinente a la pregunta, pero me gustaría decir: no utilice sumas y restas para establecer y borrar bits, ya que esos métodos son propensos a errores.
(es decir, si haces num += 1 dos veces, el resultado es equivalente a num += 2 .)

Prefiere usar las operaciones bitwise apropiadas, si su idioma elegido las proporciona:

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)
{
  this.stateF = ((num & 32) != 0);
  this.stateE = ((num & 16) != 0);
  this.stateD = ((num & 8) != 0);
  this.stateC = ((num & 4) != 0);
  this.stateB = ((num & 2) != 0);
  this.stateA = ((num & 1) != 0);
}
    
respondido por el Pharap 16.10.2018 - 08:34

Lea otras preguntas en las etiquetas