wake-up-neo.net

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

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?

21
delaccount992
//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.

21
Armen Tsirunyan

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..__ ANDed 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
12
dave
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
6
Zdeněk Pavlas

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.

1
ShadowRanger

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.

0
Malcolm McLean