Réponses:
Parce que le CPU ne peut pas adresser quoi que ce soit de plus petit qu'un octet.
bt
, bts
, btr
et btc
peuvent répondre à des bits uniques!
bt
adresse un décalage d'octet, puis teste le bit à un décalage donné, peu importe, lorsque vous spécifiez une adresse, vous entrez en octets ... les littéraux de décalage de bits deviendraient un peu verbeux (excusez le jeu de mots).
De Wikipedia :
Historiquement, un octet était le nombre de bits utilisés pour coder un seul caractère de texte dans un ordinateur et c'est pour cette raison l'élément adressable de base dans de nombreuses architectures informatiques.
L'octet est donc l' unité adressable de base , en dessous de laquelle l'architecture informatique ne peut pas adresser. Et comme il n'existe pas (probablement) d'ordinateurs prenant en charge l'octet de 4 bits, vous n'avez pas de 4 bits, bool
etc.
Cependant, si vous pouvez concevoir une telle architecture qui peut adresser 4 bits comme unité adressable de base, alors vous aurez alors une bool
taille de 4 bits, sur cet ordinateur uniquement!
int
et char
de mon message.
bool
, car char
c'est la plus petite unité adressable en C ++ , indépendamment de ce que l'architecture peut adresser avec ses propres opcodes. sizeof(bool)
doit avoir une valeur d'au moins 1, et les bool
objets adjacents doivent avoir leurs propres adresses en C ++ , donc l'implémentation doit simplement les agrandir et gaspiller de la mémoire. C'est pourquoi les champs de bits existent en tant que cas particulier: les membres de champ de bits d'une structure ne sont pas tenus d'être adressables séparément, ils peuvent donc être plus petits que a char
(bien que la structure entière ne puisse toujours pas l'être).
char
est indiqué que c'est la plus petite unité adressable en C ++?
sizeof(bool)
ne peut pas être 0,5 :-) Je suppose qu'une implémentation pourrait légalement fournir des pointeurs sous-octets comme extension, mais les objets "ordinaires" comme bool, alloués de manière ordinaire, doivent faire ce que dit la norme.
La réponse la plus simple est; c'est parce que le CPU adresse la mémoire en octets et non en bits, et les opérations au niveau du bit sont très lentes.
Cependant, il est possible d'utiliser l'allocation de taille en bits en C ++. Il existe une spécialisation std :: vector pour les vecteurs binaires, ainsi que des structures prenant des entrées de taille binaire.
À l'époque où je devais aller à l'école à pied dans une tempête de neige déchaînée, en montée dans les deux sens, et que le déjeuner était n'importe quel animal que nous pouvions traquer dans les bois derrière l'école et tuer à mains nues, les ordinateurs avaient beaucoup moins de mémoire disponible que aujourd'hui. Le premier ordinateur que j'ai jamais utilisé avait 6K de RAM. Pas 6 mégaoctets, pas 6 gigaoctets, 6 kilo-octets. Dans cet environnement, il était très logique de regrouper autant de booléens que possible dans un int, et nous utiliserions donc régulièrement des opérations pour les supprimer et les insérer.
Aujourd'hui, quand les gens se moqueront de vous pour n'avoir que 1 Go de RAM, et que le seul endroit où vous pourriez trouver un disque dur avec moins de 200 Go est dans un magasin d'antiquités, cela ne vaut tout simplement pas la peine d'emballer des bits.
Vous pouvez utiliser des champs de bits pour obtenir des entiers de taille inférieure.
struct X
{
int val:4; // 4 bit int.
};
Bien qu'il soit généralement utilisé pour mapper les structures aux modèles de bits attendus par le matériel:
struct SomThing // 1 byte value (on a system where 8 bits is a byte
{
int p1:4; // 4 bit field
int p2:3; // 3 bit field
int p3:1; // 1 bit
};
Vous pourriez avoir des booléens 1 bit et des entiers 4 et 2 bits. Mais cela ferait un ensemble d'instructions étrange sans gain de performance, car c'est une façon non naturelle de regarder l'architecture. Il est en fait logique de «gaspiller» une meilleure partie d'un octet plutôt que d'essayer de récupérer ces données inutilisées.
La seule application qui dérange pour emballer plusieurs booléens dans un seul octet, d'après mon expérience, est Sql Server.
bool
peut être un octet - la plus petite taille adressable du processeur, ou peut être plus grande. Il n'est pas inhabituel d'avoir bool
la taille de int
pour des raisons de performance. Si à des fins spécifiques (par exemple la simulation matérielle) vous avez besoin d'un type avec N bits, vous pouvez trouver une bibliothèque pour cela (par exemple, la bibliothèque GBL a une BitSet<N>
classe). Si vous êtes préoccupé par la taille de bool
(vous avez probablement un gros conteneur,), vous pouvez emballer des bits vous-même, ou utiliser std::vector<bool>
qui le fera pour vous (soyez prudent avec ce dernier, car il ne répond pas aux exigences du conteneur).
Parce qu'en général, le CPU alloue de la mémoire avec 1 octet comme unité de base, bien que certains CPU comme MIPS utilisent un mot de 4 octets.
Cependant vector
traite bool
d'une manière spéciale, avec vector<bool>
un bit pour chaque booléen est attribué.
lw
/ sw
sont beaucoup plus utilisés.
L'octet est la plus petite unité de stockage de données numériques d'un ordinateur. Dans un ordinateur, la RAM a des millions d'octets et n'importe lequel d'entre eux a une adresse. S'il avait une adresse pour chaque bit, un ordinateur pourrait gérer 8 fois moins de RAM que ce qu'il peut.
Plus d'informations: Wikipedia
Même lorsque la taille minimale possible est de 1 octet, vous pouvez avoir 8 bits d'informations booléennes sur 1 octet:
http://en.wikipedia.org/wiki/Bit_array
Le langage Julia a BitArray par exemple, et j'ai lu sur les implémentations C ++.
struct Packed { unsigned int flag1 : 1; unsigned int flag2: 1; };
. La plupart des compilateurs allouent un fichier completunsigned int
, mais ils gèrent eux-mêmes le bit-twiddling lorsque vous lisez / écrivez. Ils s'occupent également seuls des opérations modulo. C'est ununsigned small : 4
attribut qui a une valeur entre 0 et 15, et quand il devrait arriver à 16, il n'écrasera pas le bit précédent :)