Qual é o nome para armazenar / empacotar muitos estados booleanos em um número?

53

É um tipo de compactação simples onde você usa uma variável numérica para armazenar muitos estados binários / binários, usando o dobro e o fato de que cada número duplicado é 1 + a soma de todos os anteriores.

Tenho certeza de que deve ser uma técnica antiga e bem conhecida, e gostaria de saber como é chamada a referência correta. Fiz várias buscas de todas as formas possíveis para descrevê-las, mas não encontrei nada além de alguns artigos de blog, nos quais os autores parecem ter descoberto isso e não sabem como chamá-lo ( exemplo 1 , exemplo 2 ).

Por exemplo, aqui está uma implementação muito simples destinada a ilustrar o conceito:

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
}

Você também pode usar operadores bitwise, análise de números de base 2, enums ... Existem muitas maneiras mais eficientes de implementá-lo, estou interessado no nome da abordagem de forma mais geral.

    
por user568458 15.10.2018 / 10:43
fonte

3 respostas

105

É mais comumente chamado de campo de bits , e outro termo que você costuma ouvir é máscaras de bits , que são usadas para obter ou definir valores de bit individuais ou o campo de bits inteiro de uma só vez.

Muitas linguagens de programação possuem estruturas auxiliares para ajudar nisso. Como observa @BernhardHiller nos comentários, C # tem enums com sinalizadores ; Java tem a classe EnumSet .

    
por 15.10.2018 / 11:16
fonte
20

Estranho, um pouco de termos diferentes aqui, mas eu não vejo o que veio imediatamente à mente (e é no título da sua pergunta!) - Bit Packing é o que eu sempre ouvi dizer.

Eu tinha pensado que isso era realmente óbvio, mas estranhamente quando eu pesquisei este parece ser um termo que é amplamente usado mas não oficialmente definido (a Wikipedia parece redirecionar para o campo bit que é uma maneira de fazer pequenos pacotes, mas não um nome para o processo). A pesquisa pela definição parece levar a esta página:

link

O que não é ótimo para propósitos SO, mas é a melhor definição / descrição que eu posso encontrar, incluindo esta descrição sucinta: "Bit-packing é um conceito simples: use o mínimo possível para armazenar um pedaço de dados."

    
por 15.10.2018 / 18:13
fonte
13

Existem muitos termos diferentes usados para descrever isso.

Mais comumente, os bits são chamados de "sinalizadores de bits" ou "campos de bits". (No entanto, vale a pena notar que "campos de bits" às vezes se referem a um recurso específico das linguagens C e C ++, que está relacionado, mas não exatamente o mesmo.)

O inteiro em si é chamado de "matriz de bits", "conjunto de bits" ou "vetor de bits", dependendo dos usos e circunstâncias.

De qualquer maneira, extrair os bits do conjunto de bits / vetor / matriz é feito através de deslocamento e mascaramento.
(ou seja, usando uma máscara de bits .)

Para alguns exemplos de cada termo em uso ativo:

Não é realmente pertinente para a pergunta, mas eu gostaria de dizer: por favor, não use adição e subtração para definir e limpar bits, pois esses métodos são propensos a erros.
(ou seja, se você usar num += 1 duas vezes, o resultado será equivalente a num += 2 .)

Prefere usar as operações bit a bit apropriadas, se o idioma escolhido as fornecer:

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);
}
    
por 16.10.2018 / 08:34
fonte