Was ist CHAR_BIT?

Lesezeit: 6 Minuten

Zitieren des Codes zum Berechnen des ganzzahligen Absolutwerts (abs) ohne Verzweigung von http://graphics.stanford.edu/~seander/bithacks.html:

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;

Patentierte Variante:

r = (v ^ mask) - mask;

Was ist CHAR_BIT und wie benutzt man es?

  • Notiz: v + mask Kann führen zu int Überlauf – was ist undefiniertes Verhalten. (v ^ mask) - mask kann ähnliche Probleme haben.

    – chux – Wiedereinsetzung von Monica

    3. November 2021 um 21:31 Uhr


Benutzeravatar von Khaled Alshaya
Khaled Alshaya

CHAR_BIT ist die Anzahl der Bits in char. Heutzutage verwenden fast alle Architekturen 8 Bit pro Byte, aber das ist nicht immer der Fall. Einige ältere Maschinen hatten früher 7-Bit-Byte.

Es ist darin zu finden <limits.h>.

  • Einige DSPs haben 10 oder mehr Bit-Bytes.

    – Juri Robl

    8. Juli 2010 um 6:13 Uhr


  • C verlangt CHAR_BIT>=8 und erlaubt viel größere Werte für DSPs, die nur eine einzige Schriftgröße haben, oft 32 Bit. POSIX erfordert CHAR_BIT==8. Im Allgemeinen kann man jede serverorientierte oder interaktive nutzungsorientierte Mehrbenutzer-/Multitasking-Architektur annehmen, die die Möglichkeit hat, mit dem Internet verbunden zu sein oder Textdaten mit der Außenwelt auszutauschen CHAR_BIT==8.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    8. Juli 2010 um 6:24 Uhr

  • @caf: Nein, C99 benötigt die Typen int8_t und uint8_t existieren. Es existiert also eine Art Breite 8. Da sizeof jeder Typ muss mit kompatibel sein sizeof char eigentlich sizeof int8_t muss 1 sein. Also CHAR_BIT == 8. Ich habe hier etwas zu dieser Beobachtung geschrieben: gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-byte

    – Jens Gustedt

    8. Juli 2010 um 8:17 Uhr

  • @ Jens Gustedt: Bitte zitieren Sie einen Abschnitt in der C99-Spezifikation. Von den Integer-Typen mit exakter Breite sagt die C99-Spezifikation: „Diese Typen sind optional.“ (7.18.1.1/3) Die Typen minimaler Breite und schnellster Breite sind jedoch erforderlich.

    – jamesdlin

    8. Juli 2010 um 8:33 Uhr


  • @jamesdlin & caf: Entschuldigung, ich habe die Dinge verwechselt. Ja, die Anforderung, auf die ich mich bezog, stammt tatsächlich von POSIX stdint.h. Dort ist es also erforderlich, und es ist auch als gekennzeichnet Erweiterung des ISO C-Standards, ohne sich auf eine bestimmte Version dieser Norm zu beziehen. Mein Fehler.

    – Jens Gustedt

    8. Juli 2010 um 8:54 Uhr

Benutzeravatar von Plugwash
Plugwash

Der Versuch, sowohl die explizite Frage zu beantworten (was ist CHAR_BIT) und die implizite Frage (wie funktioniert das) in der ursprünglichen Frage.


EIN char in C und C++ stellt die kleinste Speichereinheit dar, die das C-Programm adressieren kann*.

CHAR_BIT in C und C++ repräsentiert die Anzahl der Bits in a char. Aufgrund anderer Anforderungen an den Zeichentyp muss es immer mindestens 8 sein. In der Praxis ist es auf allen modernen Allzweckcomputern genau 8, aber einige historische oder spezielle Systeme können höhere Werte haben.

Java hat kein Äquivalent zu CHAR_BIT oder sizeof, ist dies nicht erforderlich, da alle primitiven Typen in Java eine feste Größe haben und die interne Struktur von Objekten für den Programmierer undurchsichtig ist. Wenn Sie diesen Code nach Java übersetzen, können Sie ihn einfach ersetzen sizeof(int) * CHAR_BIT - 1 um den Festwert 31.

In diesem speziellen Code wird es verwendet, um die Anzahl der Bits in einer zu berechnen int. Beachten Sie, dass diese Berechnung davon ausgeht, dass die int type enthält keine Füllbits.

Angenommen, Ihr Compiler entscheidet sich für die Vorzeichenerweiterung bei Bitverschiebungen von vorzeichenbehafteten Zahlen und unter der Annahme, dass Ihr System die 2er-Komplementdarstellung für negative Zahlen verwendet, bedeutet dies Folgendes mask ist 0 für einen positiven oder Nullwert und -1 für einen negativen Wert.

Um eine Zweierkomplementzahl zu negieren, müssen wir ein bitweises not ausführen und dann eins hinzufügen. Entsprechend können wir eins subtrahieren und dann bitweise negieren.

Unter der Annahme, dass die Zweierkomplementdarstellung wieder -1 durch alle Einsen dargestellt wird, entspricht exklusiv oder mit -1 der bitweisen Negation.

Wenn also v null ist, wird die Zahl in Ruhe gelassen, wenn v eins ist, wird sie negiert.

Beachten Sie, dass ein signierter Überlauf in C und C++ ein undefiniertes Verhalten ist. Also mit diesem abs Implementierung auf dem negativsten Wert führt zu undefiniertem Verhalten. Dies kann behoben werden, indem Umwandlungen hinzugefügt werden, sodass die letzte Zeile des Programms in unsigned int ausgewertet wird.

* Was normalerweise, aber nicht notwendigerweise, mit der kleinsten Speichereinheit identisch ist, die die Hardware adressieren kann. Eine Implementierung kann möglicherweise mehrere Einheiten eines hardwareadressierbaren Speichers zu einer Einheit eines programmadressierbaren Speichers kombinieren oder eine Einheit eines hardwareadressierbaren Speichers in mehrere Einheiten eines programmadressierbaren Speichers aufteilen.

  • „Einfach ersetzen […] bis Wert 31″ Bei Generika ist das allerdings nicht so einfach.

    – Alexis Wilke

    3. November 2021 um 18:35 Uhr

  • Stimmt, aber wenn Sie nach Java übersetzen (ich habe Java erwähnt, weil die ursprüngliche Frage dies tat, obwohl das später herausgeschnitten wurde), hat es nicht wirklich Generika in einer Form, die für numerischen Code nützlich sind.

    – Plugwash

    3. November 2021 um 18:56 Uhr

Sie sollten sich darüber im Klaren sein, dass dieser Code vom implementierungsdefinierten Verhalten der Bitverschiebung nach rechts für Typen mit Vorzeichen abhängt. gcc verspricht, immer das vernünftige Verhalten (Vorzeichen-Bit-Erweiterung) zu geben, aber ISO C erlaubt der Implementierung, die oberen Bits mit Nullen zu füllen.

Eine Möglichkeit, dieses Problem zu umgehen:

#ifdef HAVE_SIGN_EXTENDING_BITSHIFT
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
#else
int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);
#endif

Dein Makefile oder config.h usw. definieren können HAVE_SIGN_EXTENDING_BITSHIFT zur Build-Zeit abhängig von Ihrer Plattform.

  • Ich verstehe nicht, wie dies eine akzeptierte Antwort sein kann, da sie die Frage nicht beantwortet, obwohl es ein sehr interessanter Kommentar ist.

    – qdii

    11. Mai 2013 um 18:15 Uhr

  • @Mauris: Jemand hat die Frage bearbeitet und eine Unterfrage zum Fragentitel hochgestuft. Der Originaltitel war zugegebenermaßen schrecklich, aber die Frage des OP war, wie der zitierte Bit-Hack-Code funktioniert, und “es funktioniert nicht, zumindest nicht portabel, und hier ist der Grund” ist eine nützliche Antwort.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    15. Januar 2016 um 19:28 Uhr

  • Oh ich verstehe. Leider taucht diese Frage in den Google-Suchergebnissen für sehr weit oben auf “Was ist CHAR_BIT?”, auch wenn das nicht die ursprüngliche Frage war. 🙁 Angesichts Ihrer Erklärung verstehe ich, warum Sie diese Antwort geschrieben haben, aber für die Nachwelt könnte es nützlicher sein, entweder (a) Ihre Antwort zu entfernen und sie als Kommentar zur Frage neu zu schreiben, damit @AraKs oben angezeigt wird, oder (b) Bearbeiten Sie Ihre Antwort so, dass sie den aktuellen Titel der Frage beantwortet.

    – Lynne

    15. Januar 2016 um 19:34 Uhr

  • Aufgrund der unterschiedlichen Absicht(en) zwischen der ursprünglichen Frage des OP und der Interpretation des Herausgebers scheint es, als ob die Art der ursprünglichen Anfrage unfreiwillig verschoben wurde. Obwohl beide Fragen (Original und bearbeitet) berechtigt sind, muss diese Diskrepanz angegangen werden. Ich frage jetzt: Könnte diese Antwort zu einem Wiki hinzugefügt werden? Dies würde möglicherweise Personen helfen, die nach dieser Art von Informationen suchen, obwohl dies nicht zur ursprünglichen Frage gehört. Danach könnte die Frage erneut bearbeitet werden, um sie an die ursprüngliche Anfrage von dato datuashvili anzupassen. Nur ein besorgter Leser …

    Benutzer6231921

    30. April 2017 um 15:32 Uhr

  • Ich habe mir gerade den Verlauf dieser Frage angesehen und die ursprüngliche Frage fragt eigentlich nirgendwo, wie der Code funktioniert. Die Frage, die der Herausgeber zum Titel befördert hat, ist die einzige eigentliche Frage darin.

    – Plugwash

    3. Oktober 2017 um 16:26 Uhr

1421820cookie-checkWas ist CHAR_BIT?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy