2011-01-07 2 views
83

In C++Warum ist ein boolesches 1 Byte und nicht 1 Bit Größe?

  • Warum ist ein logischer 1 Byte und nicht die 1-Bit-Größe?
  • Warum gibt es keine Typen wie 4-Bit- oder 2-Bit-Ganzzahlen?

Ich vermisse die oben genannten Dinge, wenn ein Emulator für eine CPU Schreiben

+8

in C++ können Sie "Pack" die Daten von Bit-Feldern. 'struct Gepackt {unsigned int flag1: 1; unsigned int flag2: 1; }; '. Die meisten Compiler werden einen vollständigen "unsigned int" zuweisen, jedoch behandeln sie das Bit-Twiddling selbst, wenn Sie lesen/schreiben.Auch sie beschäftigen sich selbst mit den Modulo-Operationen. Das ist ein 'unsigned small: 4' Attribut hat einen Wert zwischen 0 und 15, und wenn es 16 werden soll, überschreibt es nicht das vorhergehende Bit :) –

Antwort

148

Da die CPU nicht etwas kleiner als ein Byte ansprechen kann.

+4

Verdammt, jetzt ist das peinlich Sir – Asm

+21

Eigentlich sind die vier x86 Anweisungen 'bt',' bts', 'btr' und' btc' * können * einzelne Bits adressieren! – fredoverflow

+6

Ich denke 'bt' adressiert einen Byte-Offset und testet dann das Bit an einem gegebenen Offset, egal, wenn Sie eine Adresse angeben, die Sie in Bytes gehen ... Bit-Offset-Literale würden ein * Bit Wort * erhalten (das Wortspiel entschuldigen). – user7116

9

Die einfachste Antwort ist; Das liegt daran, dass die CPU Speicher in Bytes und nicht in Bits adressiert und bitweise Operationen sehr langsam sind.

Es ist jedoch möglich, die Bitgrößenzuordnung in C++ zu verwenden. Es gibt die std :: vector-Spezialisierung für Bitvektoren und auch Strukturen, die Einträge in Bitgröße verwenden.

+0

Nicht sicher, ich würde zustimmen, dass bitweise Operationen langsam sind. ands, nots, xors usw. sind sehr schnell. Es ist normalerweise die Implementierung der bitweisen Vorgänge, die langsam sind. Auf der Maschinenebene sind sie ziemlich schnell. Verzweigen ... jetzt ist das langsam. – Hogan

+2

Nur um es klarer zu machen, wenn Sie einen Vektor von booleans erstellen und 24 Booleans hineinlegen, nimmt es nur 3 Bytes (3 * 8). Wenn Sie einen anderen Booleschen Wert eingeben, wird ein weiteres Byte benötigt. Wenn Sie jedoch einen anderen Booleschen Wert eingeben, werden keine zusätzlichen Bytes benötigt, da die "freien" Bits im letzten Byte –

+0

verwendet werden. Ja, ich bezweifle auch, dass Bissvorgänge langsam sind. –

0

Ein Boolean wäre ein Bit, wenn Ihre CPU eine 1-Bit-CPU wäre.

Im Allgemeinen ist die Bitgröße einer CPU (zB 8 Bit, 16 Bit, 32 Bit, etc.) ein Maß für die kleinste Größe der Daten, die von der CPU manipuliert werden können - also ist es auch die Größe von der Adressraum. (Da Zeiger und Daten auf vielen Ebenen gleich sind.).

+0

Das ist nicht wahr. Die Bitzigkeit einer CPU ist traditionell die Breite des Datenbusses und dies ist nicht notwendigerweise die gleiche wie die Größe einer Adresse. 8-Bit-CPUs wie der 6502 und der 8080 hatten 16 Bit Adressbreiten. Das 16 Bit 68000 hatte 32 Bit Adressen (von denen 24 extern auf dem Adressbus sichtbar waren). Nur wenn 32-Bit-Mikroprozessoren angekommen sind, wurden die Adressbus- und Datenbusbreiten harmonisiert (dies gilt für Mikroprozessoren, in Minis und Mainframes war dies der normale Zustand von beispielsweise 16 Bit-Daten und 16-Bit-Adresse von PDP-11). – JeremyP

+0

@JeremyP: Deine Punkte sind alle wahr, wie auch immer du sagst, der "normale Stand der Dinge" ist, dass die Daten und der Adreßbus gleich sind - ich denke, wir können auf frühe Mikroprozessoren als Ausnahme, nicht als Regel hinweisen. Aber ich werde dir garantieren, dass meine Aussage nicht zu 100% korrekt ist. – Hogan

+1

Es wird Ihnen gefallen zu wissen, dass ich in der Tat ein wenig falsch in Bezug auf Minis und Mainframes war, die die Daten- und Adressgröße harmonisieren. Zum Beispiel hatte der DEC KL10 eine Benutzeradressengröße von 18 Bits und eine Datenwortgröße von 36 Bits. Ich habe auch falsch über den "Adressbus" gesprochen. Intern haben moderne 64-Bit-CPUs 64-Bit-Adressen, aber keine von ihnen hat 64 Pins für die Adressierung. – JeremyP

6

Sie könnten 1-Bit-Bools und 4 und 2-Bit-Ints haben. Aber das würde für einen seltsamen Befehlssatz ohne Leistungssteigerung sorgen, weil es eine unnatürliche Art ist, die Architektur zu betrachten. Es macht tatsächlich Sinn, einen besseren Teil eines Bytes zu "verschwenden", anstatt zu versuchen, diese ungenutzten Daten zurückzugewinnen.

Die einzige App, die mehrere Boole in ein einziges Byte packt, ist meiner Erfahrung nach Sql Server.

4

Weil ein Byte die kleinste adressierbare Einheit in der Sprache ist.

Aber Sie können bool nehmen 1 Bit zum Beispiel, wenn Sie eine Reihe von ihnen haben z. in einer Struktur, wie folgt aus:

struct A 
{ 
    bool a:1, b:1, c:1, d:1, e:1; 
}; 
1

weil der Im Allgemeinen ordnet CPU-Speicher mit 1 Byte als Grundeinheit, obwohl einige CPU wie MIPS ein 4-Byte-Wort verwenden.

Jedoch vector Angebote bool in einer speziellen Art und Weise, mit vector<bool> ein Bit für jeden Bool zugeordnet ist.

+1

Ich glaube, sogar die MIPS-CPU wird Ihnen Zugriff auf ein einzelnes Byte geben, obwohl es eine Leistungseinbuße gibt. –

+0

@Paul: Ja, Sie haben recht, aber im Allgemeinen sind die wortspezifischen 'lw' /' sw' viel weiter verbreitet. –

+0

Ich weiß nichts über MIPS, aber IA-64-Architektur erlaubt nur den Zugriff auf 64-Bit-Grenze. –

0

Das Byte ist die kleinere Einheit des digitalen Datenspeichers eines Computers. In einem Computer hat der RAM Millionen von Bytes und jeder von ihnen hat eine Adresse. Wenn es für jedes Bit eine Adresse hätte, könnte ein Computer 8 mal weniger RAM verwalten, als was er kann.

Weitere Informationen: Wikipedia

5

Sie Bit-Felder verwenden können, ganze Zahlen von Untergröße zu erhalten.

struct X 
{ 
    int val:4; // 4 bit int. 
}; 

Obwohl es in der Regel auf der Karte Strukturen genaue Hardware erwartet Bitmuster verwendet wird:

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 
}; 
20

Von Wikipedia:

Historisch gesehen, war ein Byte die Anzahl der Bits verwendet kodieren einen Computer ein einzelnes Zeichen von Text in und es ist aus diesem Grund die Grund Adr Essable Element in vielen Computer Architekturen.

So ist Byte dieadressierbare Basiseinheit, unter der Computerarchitektur nicht ansprechen kann. Und da es nicht (wahrscheinlich) Computer gibt, die 4-Bit-Byte unterstützen, haben Sie nicht 4-Bit-bool usw.

Wenn Sie jedoch eine solche Architektur entwerfen können, die 4-Bit adressieren als grundlegende adressierbare Einheit, dann haben Sie bool der Größe 4-Bit dann, nur auf diesem Computer!

+3

"Sie werden int der Größe 4-Bit dann haben, nur auf diesem Computer" - nein werden Sie nicht, weil der Standard verbietet CHAR_BIT von weniger als 8. Wenn die adressierbare Einheit auf der Architektur weniger als 8 Bits ist, dann Eine C++ - Implementierung muss nur ein Speichermodell darstellen, das sich vom Speichermodell der zugrunde liegenden Hardware unterscheidet. –

+0

@Steve: oops ... das habe ich übersehen. "Int" und "char" aus meinem Post entfernt. – Nawaz

+0

Sie können auch kein 4-Bit 'bool' haben, da' char' die kleinste adressierbare Einheit * in C++ * ist, unabhängig davon, was die Architektur mit ihren eigenen Opcodes adressieren kann. 'sizeof (bool)' muss einen Wert von mindestens 1 haben, und benachbarte 'bool' Objekte müssen ihre eigenen Adressen * in C++ * haben, also muss die Implementierung sie nur vergrößern und Speicher verschwenden. Deshalb gibt es Bitfelder als Sonderfall: Die Bitfeldelemente einer Struktur müssen nicht separat adressierbar sein, daher können sie kleiner sein als ein 'char' (obwohl die ganze Struktur immer noch nicht sein kann). –

1

bool kann ein Byte sein - die kleinste adressierbare Größe der CPU, oder kann größer sein. Es ist nicht ungewöhnlich, dass bool aus Leistungsgründen die Größe int hat. Wenn für bestimmte Zwecke (z. B. Hardwaresimulation) ein Typ mit N Bits benötigt wird, können Sie eine Bibliothek dafür finden (z. B. die GBL-Bibliothek hat die Klasse BitSet<N>). Wenn Sie mit der Größe von bool betroffen sind (Sie haben wahrscheinlich einen großen Behälter,), dann können Sie Bits packen selbst oder std::vector<bool> verwenden, die es für Sie tun wird (mit dieser vorsichtig sein, da es nicht Behälter requirments nicht erfüllt).

8

Zurück in den alten Tagen, als ich in einem rasenden Schneesturm in beide Richtungen zur Schule gehen musste, und Mittagessen war was Tier wir in den Wäldern hinter der Schule aufspüren und mit unseren bloßen Händen töten konnten, hatten Computer viel weniger Speicher verfügbar als heute. Der erste Computer, den ich jemals benutzt habe, hatte 6K RAM. Nicht 6 Megabyte, nicht 6 Gigabyte, 6 Kilobyte. In dieser Umgebung war es sehr sinnvoll, so viele Boolesche Werte wie möglich in einen int-Wert zu packen. Daher verwenden wir regelmäßig Operationen, um sie herauszunehmen und einzufügen.

Heute, wenn die Leute dich verspotten mit nur 1 GB RAM, und der einzige Ort, an dem man eine Festplatte mit weniger als 200 GB finden kann, ist ein Antiquitätenladen, es lohnt sich einfach nicht, die Sachen zu packen.

+0

Außer bei Flaggen. Dinge wie Einstellen mehrerer Optionen auf etwas ... z. 00000001 + 00000100 = 00000101. – Armstrongest

+0

@Atomix: Das mache ich fast nie mehr. Wenn ich zwei Flags brauche, erstelle ich zwei boolesche Felder. Ich habe Code geschrieben, wo ich solche Flags verpacke und dann "if flags & 0x110! = 0 then" oder ähnliches schreibe, aber das ist kryptisch und heutzutage mache ich normalerweise getrennte Felder und schreibe "if fooFlag || barFlag " stattdessen. Ich würde die Möglichkeit von Fällen nicht ausschließen, in denen das Packen von Flags aus irgendeinem Grund besser ist, aber es ist nicht länger notwendig, Speicher wie früher zu sparen. – Jay

+0

Ja, ich dachte an Flaggen, die bereits in eine Sprache gebrannt sind. Zum Beispiel in C# Ich bin sicher, dass RegexOptions ein Flag verwendet, um Optionen einzustellen: 'RegexOptions.CultureInvariant + RegexOptions.IgnoreCase' – Armstrongest

0

Überlegen Sie, wie Sie diese in Ihrem Emulator Ebene implementieren würde ...

bool a[10] = {false}; 

bool &rbool = a[3]; 
bool *pbool = a + 3; 

assert(pbool == &rbool); 
rbool = true; 
assert(*pbool); 
*pbool = false; 
assert(!rbool); 
1

Selbst wenn die Mindestgröße möglich ist 1 Byte, können Sie 8-Bit-Boolesche Informationen haben über 1 Byte:

http://en.wikipedia.org/wiki/Bit_array

Julia Sprache hat BitArray zum Beispiel, und ich lese über C++ - Implementierungen.