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 wird es verwendet?
c
bit-manipulation
dato datuashvili
quelle
quelle
CHAR_BIT
?" Sehr häufig auf. , 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 zu der Frage neu zu schreiben, damit @ AraK's oben angezeigt wird, oder (b) Bearbeiten Sie Ihre Antwort so, dass sie den aktuellen Titel der Frage beantwortet.CHAR_BIT
ist die Anzahl der Bits inchar
. Heutzutage verwenden fast alle Architekturen 8 Bit pro Byte, dies ist jedoch nicht immer der Fall. Einige ältere Maschinen hatten früher 7-Bit-Byte.Es kann in gefunden werden
<limits.h>
.quelle
CHAR_BIT>=8
und erlaubt viel größere Werte für DSPs, die nur eine einzige Typgröße haben, häufig 32 Bit. POSIX erfordertCHAR_BIT==8
. Im Allgemeinen können Sie von jeder server- oder interaktionsorientierten Architektur für mehrere Benutzer / Multitasking ausgehen, bei der die Möglichkeit besteht, mit dem Internet verbunden zu werden oder Textdaten mit der Außenwelt auszutauschenCHAR_BIT==8
.int8_t
und mussuint8_t
existieren. Es gibt also einen Typ von Breite 8. Dasizeof
jeder Typ mitsizeof char
tatsächlich kompatibel seinsizeof int8_t
muss, muss er 1 seinCHAR_BIT == 8
. Ich habe hier etwas über diese Beobachtungstdint.h
. Dort ist es also erforderlich, und es wird auch als Erweiterung des ISO C-Standards gekennzeichnet , ohne auf eine bestimmte Version dieses Standards Bezug zu nehmen. Mein Fehler.Der Versuch, sowohl die explizite Frage (was ist CHAR_BIT) als auch die implizite Frage (wie funktioniert das) in der ursprünglichen Frage zu beantworten.
Ein Zeichen 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 einem Zeichen. Aufgrund anderer Anforderungen an den Char-Typ muss er immer mindestens 8 betragen. In der Praxis sind es auf allen modernen Allzweckcomputern genau 8, aber einige historische oder spezialisierte Systeme können höhere Werte haben.
Java hat keine Entsprechung zu CHAR_BIT oder sizeof, es ist 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 einfach "sizeof (int) * CHAR_BIT - 1" durch den festen Wert 31 ersetzen.
In diesem speziellen Code wird es verwendet, um die Anzahl der Bits in einem int zu berechnen. Beachten Sie, dass bei dieser Berechnung davon ausgegangen wird, dass der Typ int keine Füllbits enthält.
Angenommen, Ihr Compiler wählt die Vorzeichenverlängerung bei Bitverschiebungen vorzeichenbehafteter Zahlen und nimmt an, dass Ihr System die 2s-Komplementdarstellung für negative Zahlen verwendet, bedeutet dies, dass "MASK" für einen positiven oder Nullwert 0 und für einen negativen Wert -1 ist.
Um eine Zweierkomplementzahl zu negieren, müssen wir eine bitweise nicht ausführen und dann eine hinzufügen. Ebenso können wir einen subtrahieren und ihn dann bitweise negieren.
Wiederum unter der Annahme, dass die Zweierkomplementdarstellung -1 durch alle Einsen dargestellt wird, ist exklusiv oder mit -1 gleichbedeutend mit einer bitweisen Negation.
Wenn also v Null ist, bleibt die Zahl allein, wenn v eins ist, wird sie negiert.
Beachten Sie, dass der signierte Überlauf in C und C ++ ein undefiniertes Verhalten ist. Die Verwendung dieser ABS-Implementierung für den negativsten Wert führt also zu undefiniertem Verhalten. Dies kann durch Hinzufügen von Casts behoben werden, sodass die letzte Zeile des Programms in int ohne Vorzeichen ausgewertet wird.
* Dies entspricht normalerweise, aber nicht unbedingt der kleinsten Speichereinheit, die die Hardware adressieren kann. Eine Implementierung kann möglicherweise mehrere Einheiten des hardwareadressierbaren Speichers zu einer Einheit des programmadressierbaren Speichers kombinieren oder eine Einheit des hardwareadressierbaren Speichers in mehrere Einheiten des programmadressierbaren Speichers aufteilen.
quelle