Ich muss den Wert des niederwertigsten Bits (LSB) und des höchstwertigen Bits (MSB) einer Ganzzahl in C/C++ überprüfen. Wie würde ich das tun?
Überprüfen Sie den Wert des niederwertigsten Bits (LSB) und des höchstwertigen Bits (MSB) in C/C++
dekonto992
Armen Tsirunyan
//int value;
int LSB = value & 1;
Alternative (was theoretisch nicht tragbar ist, aber praktisch – siehe Steves Kommentar)
//int value;
int LSB = value % 2;
Einzelheiten:
Die zweite Formel ist einfacher. Der %-Operator ist der Restoperator. Das LSB einer Zahl ist 1, wenn sie eine ungerade Zahl ist, andernfalls 0. Also überprüfen wir den Rest der Division mit 2. Die Logik der ersten Formel ist folgende: Zahl 1 in binär ist dies:
0000...0001
Wenn Sie dies binär UND mit einer beliebigen Zahl machen, sind alle Bits des Ergebnisses 0 außer dem letzten, weil 0 UND alles andere 0 ist. Das letzte Bit des Ergebnisses ist 1, wenn das letzte Bit Ihrer Zahl 1 war Weil 1 & 1 == 1
und 1 & 0 == 0
Dies ist ein gutes Tutorial für bitweise Operationen.
HTH.
-
@Kobie: Verstehst du die Logik der Formeln oder soll ich das genauer erklären?
– Armen Tsirunyan
11. Juli 2011 um 8:56 Uhr
-
IMO das
%2
ist albern, denn obwohl es in der Praxis funktioniert, liegt das nur daran, dass in der Praxis alle C++-Implementierungen die Zweierkomplementdarstellung für negative Ganzzahlen verwenden. In der Theorie funktioniert es nicht unbedingt, da in der Theorie-1
könnte sein LSB frei haben (Einerkomplement). Wenn der Test für die ist letztes Stückverwenden Sie dann a bitweise Operator, gegenüber dem Modulo-Operator, der nichts mit Bits zu tun hat 🙂– Steve Jessop
11. Juli 2011 um 9:07 Uhr
-
@Steve: Fairer Punkt, deshalb habe ich es als Alternative aufgeführt, aber ich werde die Antwort trotzdem bearbeiten, um sie klarer zu machen
– Armen Tsirunyan
11. Juli 2011 um 9:08 Uhr
-
@Kobie: Eine mögliche Lösung wird ausgeführt
variable & 1
bis Sie nach rechts schalten könnenvariable
. Eine Art:for (;variable != 0; variable >> 1) { ... }
. Das LetzteLSB
Wert entspricht demMSB
.– dave
11. Juli 2011 um 9:33 Uhr
-
@Kerrek: oh, sicher … das ist eine Endlosschleife 🙂
– dave
11. Juli 2011 um 10:21 Uhr
dave
Sie können so etwas tun:
#include <iostream>
int main(int argc, char **argv)
{
int a = 3;
std::cout << (a & 1) << std::endl;
return 0;
}
Auf diese Weise Sie AND
Ihre Variable mit dem LSB, weil
3: 011
1: 001
in 3-Bit-Darstellung. Also Sein AND
:
AND
-----
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
Sie können wissen, ob LSB 1 ist oder nicht.
bearbeiten: MSB finden.
Erstmal lesen Endianität Artikel zu vereinbaren, was MSB
meint. In den folgenden Zeilen nehmen wir an, mit Big-Endian-Notation zu arbeiten.
Um die zu finden MSB
im folgenden Ausschnitt konzentrieren wir uns auf die Anwendung einer Rechtsverschiebung bis zum MSB
wird sein AND
ed mit 1
. Betrachten Sie den folgenden Code:
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
unsigned int a = 128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we're looking for
// sizeof(unsigned int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(unsigned int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out '0', because the 32-bit representation of
// unsigned int 128 is:
// 00000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
Wenn Sie drucken MSB
außerhalb des Zyklus erhalten Sie 0
. Wenn Sie den Wert von ändern a
:
unsigned int a = UINT_MAX; // found in <limits.h>
MSB
wird sein 1
denn seine 32-Bit-Darstellung ist:
UINT_MAX: 11111111111111111111111111111111
Wenn Sie jedoch dasselbe mit a tun vorzeichenbehaftete Ganzzahl die Dinge werden anders sein.
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
int a = -128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we're looking for
// sizeof(int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out '1', because the 32-bit representation of
// int -128 is:
// 10000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
Wie ich im Kommentar unten sagte, die MSB
von a positive ganze Zahl ist immer 0
während MSB
von a negative ganze Zahl ist immer 1
.
Sie können die INT_MAX 32-Bit-Darstellung überprüfen:
INT_MAX: 01111111111111111111111111111111
Jetzt. Warum der Zyklus verwendet sizeof()
? Wenn Sie den Zyklus einfach so machen, wie ich es im Kommentar geschrieben habe: (sorry für die =
fehlt im Kommentar)
for (; a != 0; a >>= 1)
MSB = a & 1;
Sie erhalten 1
immer, da C++ die ‘Zero-Pad-Bits’ nicht berücksichtigt (weil Sie angegeben haben a != 0
als Exit-Anweisung) höher als die höchste 1
. Zum Beispiel haben wir für 32-Bit-Ganzzahlen:
int 7 : 00000000000000000000000000000111
^ this will be your fake MSB
without considering the full size
of the variable.
int 16: 00000000000000000000000000010000
^ fake MSB
-
MSB
undLSB
hängen von der Architektur ab. Wenn Sie die Big-Endian-Notation verwenden, wird dieMSB
ist das Bit ganz links. Nicht das erste Nicht-Null-Ereignis, noch alles andere. Unter Verwendung der Big-Endian-Notation wird dieMSB
in vorzeichenbehafteten Ganzzahlen bestimmt das Vorzeichen (0: positive Zahl, 1: negative Zahl). DasLSB
bestimmt, ob die Zahl gerade oder ungerade ist (0: gerade, 1: ungerade).– dave
11. Juli 2011 um 14:05 Uhr
-
@Kobie: Ich habe die Antwort bearbeitet, einschließlich eines Links zu Wikipedia über Endianess.
– dave
11. Juli 2011 um 14:27 Uhr
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
-
Ist das Verschieben von vorzeichenbehafteten Ganzzahlen nicht nicht portierbar?
– Guilherme Bernal
30. November 2013 um 13:45 Uhr
-
Ich denke, es würde auf Big-Endian-Systemen brechen … aber zitieren Sie mich nicht darauf
– Hansenrik
24. Februar 2015 um 17:38 Uhr
Andere haben es schon erwähnt:
int LSB = value & 1;
um das niederwertigste Bit zu erhalten. Aber es gibt einen betrügerischen Weg, um das MSB zu bekommen, als erwähnt wurde. Wenn der Wert bereits ein signierter Typ ist, tun Sie einfach Folgendes:
int MSB = value < 0;
Wenn es sich um eine vorzeichenlose Größe handelt, wandeln Sie sie in den vorzeichenbehafteten Typ derselben Größe um, z. B. if value
wurde als deklariert unsigned
tun:
int MSB = (int)value < 0;
Ja, offiziell, nicht portierbar, undefiniertes Verhalten, was auch immer. Aber auf jedem Zweierkomplementsystem und jedem Compiler dafür, den ich kenne, funktioniert es zufällig; Schließlich ist das High-Bit das Vorzeichenbit. Wenn also die vorzeichenbehaftete Form negativ ist, dann ist das MSB 1, wenn es nicht negativ ist, ist das MSB 0. Praktischerweise entspricht ein vorzeichenbehafteter Test für negative Zahlen dem Abrufen von MSB.
LSB ist einfach. Nur x & 1.
MSSB ist etwas kniffliger, da Bytes möglicherweise nicht 8 Bits und sizeof(int) nicht 4 Bits sind und rechts möglicherweise Füllbits vorhanden sind.
Mit einer vorzeichenbehafteten Ganzzahl meinen Sie auch das Vorzeichenbit des MS-Wertbits.
Wenn Sie das Zeichenbit meinen, ist das Leben einfach. Es ist nur x < 0
Wenn Sie das Bit mit dem höchsten Wert meinen, vollständig tragbar zu sein.
int answer = 0;
int rack = 1;
int mask = 1;
while(rack < INT_MAX)
{
rack << = 1;
mask << = 1;
rack |= 1;
}
return x & mask;
Das ist ein langwieriger Weg, es zu tun. In Wirklichkeit
x & (1 << (sizeof(int) * CHAR_BIT) - 2); wird ziemlich tragbar genug sein und Ihre ints werden keine Füllbits haben.