C'est une sorte de compression simple où vous utilisez une variable numérique pour stocker de nombreux états booléens/binaires, en utilisant le doublage et le fait que chaque nombre doublant est 1 + la somme de tous les précédents.
Je suis sûr que ce doit être une vieille technique bien connue, j'aimerais savoir comment on l'appelle pour s'y référer correctement. J'ai fait plusieurs recherches sur toutes les façons dont je peux penser pour le décrire, mais je n'ai rien trouvé au-delà de certains articles de blog où les auteurs de l'article semblent avoir compris cela eux-mêmes et ne savent pas comment l'appeler, non plus ( exemple 1 , exemple 2 ).
Par exemple, voici une implémentation très simple destinée à illustrer le concept:
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
}
Vous pouvez également utiliser des opérateurs au niveau du bit, l'analyse des nombres en base 2, des énumérations ... Il existe de nombreuses façons plus efficaces de l'implémenter, je m'intéresse plus généralement au nom de l'approche.
Il est le plus souvent appelé champ de bits , et un autre terme que vous entendrez souvent est masques de bits , qui sont utilisés pour obtenir ou définir des valeurs de bits individuelles ou le bit entier champ à la fois.
De nombreux langages de programmation ont des structures auxiliaires pour aider à cela. Comme le note @BernhardHiller dans les commentaires, C # a énumère les drapeaux ; Java a la classe EnumSet .
Étrange, un peu de termes différents ici, mais je ne vois pas celui qui m'est immédiatement venu à l'esprit (et c'est dans le titre de votre question!) - Bit Packing est ce que j'ai toujours entendu dire.
J'avais pensé que c'était vraiment évident, mais étrangement quand je le recherche sur Google, cela semble être un terme largement utilisé mais pas officiellement défini (Wikipedia semble rediriger vers le champ de bits qui est un moyen de faire un emballage de bits, mais pas un nom pour le processus). La recherche de la définition semble mener à cette page:
http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101
Ce qui n'est pas idéal pour SO fins mais c'est la meilleure définition/description que je puisse trouver, y compris cette description succincte: "Le compactage de bits est un concept simple: utilisez le moins de bits possible pour stocker un élément de données. "
Il existe de nombreux termes différents utilisés pour décrire cela.
Le plus souvent, les bits sont appelés "drapeaux de bits" ou "champs de bits".
(Cependant, il convient de noter que les "champs de bits" se réfèrent parfois à une caractéristique spécifique des langages C et C++, qui est liée mais pas exactement la même.)
L'entier lui-même est appelé diversement soit un "tableau de bits", un "ensemble de bits" ou un "vecteur de bits", selon les usages et les circonstances.
Dans les deux cas, l'extraction des bits de l'ensemble de bits/vecteur/tableau se fait par décalage et masquage.
(c'est-à-dire en utilisant un masque de bits .)
Pour quelques exemples de chaque terme utilisé activement:
std::bitset
BitSet
BitArray
bitvector
, bitarray
et bitset
bitarray
et un projet BitVector
Ce n'est pas vraiment pertinent pour la question, mais je voudrais dire: veuillez ne pas utiliser l'addition et la soustraction pour définir et effacer les bits car ces méthodes sont sujettes à erreur.
(c'est-à-dire si vous faites num += 1
deux fois, le résultat est équivalent à num += 2
.)
Préférez utiliser les opérations au niveau du bit appropriées à la place, si votre langue choisie les fournit:
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);
}