Ich muss den Wert des niedrigstwertigen Bits (LSB) und des höchstwertigen Bits (MSB) einer Ganzzahl in C/C++ überprüfen. Wie würde ich das machen?
//int value;
int LSB = value & 1;
Alternativ (was theoretisch nicht portabel ist, aber praktisch ist es - siehe Steves Kommentar)
//int value;
int LSB = value % 2;
Details: Die zweite Formel ist einfacher. Der Operator% ist der Restoperator. Das LSB einer Zahl ist 1, wenn es eine ungerade Zahl ist, andernfalls 0. Wir prüfen also den Rest der Division mit 2. Die Logik der ersten Formel lautet: Nummer 1 in Binär ist folgende:
0000...0001
Wenn Sie ein binäres AND mit einer beliebigen Zahl haben, werden alle Bits des Ergebnisses 0 sein, außer das letzte, da 0 UND alles andere 0 ist. Das letzte Bit des Ergebnisses ist 1, wenn das letzte Bit Ihrer Zahl 1 ist weil 1 & 1 == 1
und 1 & 0 == 0
This ist ein gutes Tutorial für bitweise Operationen.
HTH.
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 AND
deine Variable mit dem LSB, weil
3: 011
1: 001
in 3-Bit-Darstellung. Also AND
sein:
AND
-----
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
Sie können feststellen, ob LSB 1 ist oder nicht.
edit: MSB suchen.
Lesen Sie zunächst den Endianess -Artikel, um sich darauf zu einigen, was MSB
bedeutet. In den folgenden Zeilen nehmen wir an, mit der Big-Endian-Notation zu arbeiten.
Um die MSB
zu finden, konzentrieren wir uns im folgenden Ausschnitt auf eine Rechtsverschiebung, bis die MSB
mit 1
..__ AND
ed ist. 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 MSB
außerhalb des Zyklus drucken, erhalten Sie 0
. Wenn Sie den Wert von a
ändern:
unsigned int a = UINT_MAX; // found in <limits.h>
MSB
wird 1
sein, da die 32-Bit-Darstellung Folgendes ist:
UINT_MAX: 11111111111111111111111111111111
Wenn Sie dasselbe mit einer mit Vorzeichen versehenen Ganzzahl tun, werden die Dinge jedoch 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 in dem Kommentar unten gesagt habe, ist die MSB
einer positiven ganzen Zahl immer 0
, während die MSB
einer negativen ganzen Zahl immer 1
ist.
Sie können die 32-Bit-Darstellung von INT_MAX überprüfen:
INT_MAX: 01111111111111111111111111111111
Jetzt. Warum verwendet der Zyklus sizeof()
? Wenn Sie den Zyklus einfach wie in dem Kommentar beschrieben ausführen: (Entschuldigung für den =
fehlt in Kommentar)
for (; a != 0; a >>= 1)
MSB = a & 1;
sie erhalten 1
immer, da C++ die 'Nullpunkt-Bits' (da Sie a != 0
als Beendigungsanweisung angegeben haben) nicht höher als das höchste 1
berücksichtigt. Zum Beispiel für 32-Bit-Ganzzahlen haben wir:
int 7 : 00000000000000000000000000000111
^ this will be your fake MSB
without considering the full size
of the variable.
int 16: 00000000000000000000000000010000
^ fake MSB
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
Andere haben bereits erwähnt:
int LSB = value & 1;
um das geringste Bit zu bekommen. Aber es gibt einen etwas schäbigeren Weg, um das MSB zu bekommen, als erwähnt wurde. Wenn der Wert bereits ein signierter Typ ist, machen Sie einfach Folgendes:
int MSB = value < 0;
Wenn es sich um eine vorzeichenlose Menge handelt, gießen Sie sie in den vorzeichenbehafteten Typ der gleichen Größe, z. Wenn value
als unsigned
deklariert wurde, führen Sie folgende Schritte aus:
int MSB = (int)value < 0;
Ja, offiziell, nicht portabel, undefiniertes Verhalten, wie auch immer. Aber auf jedem Zwei-Komplement-System und jedem Compiler, der mir bekannt ist, funktioniert es; Immerhin ist das High-Bit das Vorzeichen-Bit. Wenn also die vorzeichenbehaftete Form negativ ist, dann ist das MSB 1, wenn es nicht negativ ist, ist das MSB 0. Daher ist ein vorzeichenbehafteter Test für negative Zahlen äquivalent zum Abrufen des MSB.
LSB ist einfach. Nur x & 1.
MSSB ist etwas kniffliger, da Byte nicht aus 8 Bits und sizeof (int) nicht aus 4 bestehen kann und es möglicherweise Auffüllbits nach rechts gibt.
Meinen Sie mit einer vorzeichenbehafteten Ganzzahl auch das Vorzeichenbit des MS-Wertbits.
Wenn Sie das Zeichenbit meinen, ist das Leben einfach. Es ist nur x <0
Wenn Sie das höchstwertige Wert-Bit meinen, müssen Sie vollständig portabel 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 eine langwierige Art, es zu tun. In Wirklichkeit
x & (1 << (sizeof (int) * CHAR_BIT) - 2); ist ziemlich tragbar genug und Ihre Ints haben keine Füllungsbits.