C'est une sorte de compression simple dans laquelle vous utilisez une variable numérique pour stocker plusieurs états booléens / binaires, en utilisant le doublage et le fait que chaque nombre de doublage est égal à 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 tous les moyens possibles pour le décrire, mais je n'ai rien trouvé au-delà de certains articles de blog où les auteurs de l'article semblent l'avoir compris eux-mêmes et ne savent pas comment l'appeler ( 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 des bits, l'analyse du nombre de base 2, les énumérations ... Il existe de nombreuses manières plus efficaces de l'implémenter. Je m'intéresse plus généralement au nom de l'approche.
la source
enums
en a et ils peuvent avoir unFlags
attribut. Ils pourraient rendre votre code beaucoup plus simple.bool
est généralement stocké en interne sous la forme d'un entier de 32 bits. En tant que tel, l'emballage peut faire la différence d'un facteur 32. C'est beaucoup. Je veux dire, nous, les programmeurs, sommes toujours prêts à jeter la moitié de nos ressources, mais je suis généralement réticent à en rejeter 97%. De tels facteurs de gaspillage peuvent facilement faire la différence entre la capacité d'exécuter des cas d'utilisation importants et le manque de mémoire.Réponses:
C'est le plus souvent appelé champ de bits , et un autre terme que vous entendrez souvent est celui de masques de bits , qui sont utilisés pour obtenir ou définir des valeurs de bits individuelles ou le champ de bits entier à la fois.
De nombreux langages de programmation ont des structures auxiliaires pour aider à cela. Comme @BernhardHiller le note dans les commentaires, C # a des énumérations avec des drapeaux ; Java a la classe EnumSet .
la source
BitArray
, ce qui permet de stocker une quantité arbitraire de bits et de les indexer (alors que les indicateurs sont limités à un type entier et sont destinés à être utilisés comme masques).Étrange, pas mal de termes différents ici mais je ne vois pas celui qui m’a tout de suite préoccupé (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 j’ai cherché sur Google, c’est un terme qui est largement utilisé mais qui n’est pas défini officiellement (Wikipédia semble rediriger vers un champ 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 génial pour SO, mais c’est la meilleure définition / description que je puisse trouver, y compris cette description succincte: "La compression de bits est un concept simple: utilisez aussi peu que possible pour stocker une donnée."
la source
char
tableau en mettant deuxchar
s en unint
.Il existe de nombreux termes différents utilisés pour décrire cela.
Le plus souvent, les bits sont appelés "indicateurs de bits" ou "champs de bits".
(Toutefois, il convient de noter que les "champs de bits" font parfois référence à une fonctionnalité spécifique des langages C et C ++, qui est liée mais pas tout à fait la même.)
L'entier lui-même est désigné indifféremment comme un "tableau de bits", un "ensemble de bits" ou un "vecteur de bits", en fonction des usages et des circonstances.
Dans les deux cas, l'extraction des bits de l'ensemble de bits / du vecteur / de la matrice s'effectue par décalage et masquage.
(ie en utilisant un masque de bits .)
Pour quelques exemples de chaque terme en utilisation active:
std::bitset
BitSet
BitArray
bitvector
,bitarray
etbitset
bitarray
projet et unBitVector
projetCe n'est pas vraiment pertinent pour la question, mais j'aimerais dire: n'utilisez pas d'addition et de soustraction pour définir et effacer des bits, car ces méthodes sont sujettes aux erreurs.
(Par exemple, si vous faites
num += 1
deux fois, le résultat est équivalent ànum += 2
.)Préférez utiliser les opérations appropriées au niveau des bits, si la langue de votre choix les fournit:
la source
this.stateF = (num & 32) ? true : false
, etc. Pas besoin de muternum
pendant l'extraction des valeurs.+
et-
. Je suis maintenant allé mieux et utilisé à la!= 0
place d'un ternaire, ce qui me semble plus concis tout en restant exposé.