Überprüfen Sie den Wert des niederwertigsten Bits (LSB) und des höchstwertigen Bits (MSB) in C/C++

Lesezeit: 6 Minuten

Benutzer-Avatar
dekonto992

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?

Benutzer-Avatar
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önnen variable. Eine Art: for (;variable != 0; variable >> 1) { ... }. Das Letzte LSB Wert entspricht dem MSB.

    – dave

    11. Juli 2011 um 9:33 Uhr


  • @Kerrek: oh, sicher … das ist eine Endlosschleife 🙂

    – dave

    11. Juli 2011 um 10:21 Uhr

Benutzer-Avatar
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 MSBim folgenden Ausschnitt konzentrieren wir uns auf die Anwendung einer Rechtsverschiebung bis zum MSB wird sein ANDed 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 1denn 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 0wä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 und LSB hängen von der Architektur ab. Wenn Sie die Big-Endian-Notation verwenden, wird die MSB ist das Bit ganz links. Nicht das erste Nicht-Null-Ereignis, noch alles andere. Unter Verwendung der Big-Endian-Notation wird die MSB in vorzeichenbehafteten Ganzzahlen bestimmt das Vorzeichen (0: positive Zahl, 1: negative Zahl). Das LSB 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 unsignedtun:

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.

1364900cookie-checkÜberprüfen Sie den Wert des niederwertigsten Bits (LSB) und des höchstwertigen Bits (MSB) in C/C++

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

Privacy policy