É uma espécie de compactação simples, na qual você usa uma variável numérica para armazenar muitos estados booleanos / binários, usando a duplicação e o fato de que todo número de duplicação é 1 + a soma de todos os anteriores.
Tenho certeza de que deve ser uma técnica antiga e bem conhecida. Gostaria de saber como é chamada para se referir a ela corretamente. Fiz várias pesquisas de todas as formas possíveis para descrevê-lo, mas não encontrei nada além de alguns artigos de blog em que os autores do artigo parecem ter descoberto isso por conta própria e também 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 bit a bit, análise de número de base 2, enumerações ... Existem muitas maneiras mais eficientes de implementá-lo. Estou interessado no nome da abordagem em geral.
fonte
enums
e eles podem ter umFlags
atributo. Eles poderiam tornar seu código muito mais simples.bool
geralmente é armazenado como um inteiro de 32 bits internamente. Como tal, a embalagem pode fazer a diferença de um fator de 32. Isso é realmente muito. Quero dizer, nós programadores estamos sempre prontos para jogar fora metade de nossos recursos, mas geralmente reluto em jogar 97% deles. Esses fatores de desperdício podem facilmente fazer a diferença entre poder executar casos de uso importantes e ficar sem memória.Respostas:
É mais comumente chamado de campo de bits , e outro termo que você costuma ouvir é máscaras de bits , usadas para obter ou definir valores de bits individuais ou o campo de bits inteiro de uma só vez.
Muitas linguagens de programação possuem estruturas auxiliares para ajudar nisso. Como o @BernhardHiller observa nos comentários, o C # possui enumerações com sinalizadores ; Java tem a classe EnumSet .
fonte
BitArray
, o que permite armazenar uma quantidade arbitrária de bits e indexá-los (enquanto os sinalizadores são limitados a um tipo inteiro e devem ser usados como máscaras).Estranho, termos bastante diferentes aqui, mas não vejo o que veio à mente imediatamente (e está no título da sua pergunta!) - Bit Packing é o que sempre ouvi dizer.
Eu pensei que isso era realmente óbvio, mas estranhamente, quando pesquiso no Google, esse parece ser um termo amplamente usado, mas não oficialmente definido (a Wikipedia parece redirecionar para o campo de bits, que é uma maneira de empacotar bit, mas não um nome para o processo). A busca pela definição parece levar a esta página:
http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101
O que não é ótimo para fins de SO, mas é a melhor definição / descrição que posso encontrar, incluindo esta descrição sucinta: "Empacotar bit é um conceito simples: use o mínimo possível para armazenar um pedaço de dados".
fonte
char
matriz colocando doischar
s em umint
.Existem muitos termos diferentes usados para descrever isso.
Geralmente, 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 refere a um recurso específico das linguagens C e C ++, que está relacionado, mas não exatamente o mesmo.
O inteiro em si é referido de várias maneiras como "matriz de bits", "conjunto de bits" ou "vetor de bits", dependendo do uso e das circunstâncias.
De qualquer maneira, a extração dos bits do conjunto de bits / vetor / matriz é feita através de deslocamento e mascaramento.
(ou seja, usando uma máscara de bit .)
Para alguns exemplos de cada termo em uso ativo:
std::bitset
BitSet
BitArray
bitvector
,bitarray
ebitset
bitarray
projeto e umBitVector
projetoNão é realmente pertinente à 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ê fizer
num += 1
duas vezes, o resultado é equivalente anum += 2
.)Prefira usar as operações bit a bit apropriadas, se o idioma escolhido fornecer:
fonte
this.stateF = (num & 32) ? true : false
, etc. Não há necessidade de alterarnum
enquanto você extrai os valores.+
e-
. Agora, eu fui um melhor e usei em!= 0
vez de um ternário, o que eu acho mais conciso enquanto ainda estou sendo expclit.