Wie erhalte ich Bit-für-Bit-Daten von einem ganzzahligen Wert in C?

Lesezeit: 5 Minuten

Benutzeravatar von Badr
Badr

Ich möchte Bits einer Dezimalzahl extrahieren.

Zum Beispiel ist 7 binär 0111, und ich möchte 0 1 1 1 erhalten, alle Bits, die in bool gespeichert sind. Wie kann ich das tun?

OK, eine Schleife ist keine gute Option, kann ich dafür etwas anderes tun?

Benutzeravatar von Zeigefinger
Zeigefinger

Wenn Sie das k-te Bit von n wollen, dann tun Sie es

(n & ( 1 << k )) >> k

Hier erstellen wir eine Maske, wenden die Maske auf n an und verschieben dann den maskierten Wert nach rechts, um genau das gewünschte Bit zu erhalten. Wir könnten es ausführlicher schreiben als:

    int mask =  1 << k;
    int masked_n = n & mask;
    int thebit = masked_n >> k;

Sie können mehr über Bitmaskierung lesen hier.

Hier ist ein Programm:

#include <stdio.h>
#include <stdlib.h>

int *get_bits(int n, int bitswanted){
  int *bits = malloc(sizeof(int) * bitswanted);

  int k;
  for(k=0; k<bitswanted; k++){
    int mask =  1 << k;
    int masked_n = n & mask;
    int thebit = masked_n >> k;
    bits[k] = thebit;
  }

  return bits;
}

int main(){
  int n=7;

  int  bitswanted = 5;

  int *bits = get_bits(n, bitswanted);

  printf("%d = ", n);

  int i;
  for(i=bitswanted-1; i>=0;i--){
    printf("%d ", bits[i]);
  }

  printf("\n");
}

  • (n >> k) & 1 ist gleichermaßen gültig und erfordert keine Berechnung der Maske, da die Maske aufgrund der Verschiebung vor der Maskierung konstant ist und nicht umgekehrt.

    – Jo

    22. Mai 2013 um 15:37 Uhr


  • @Joe kannst du das erklären, vielleicht in einer Antwort, bitte?

    – Dan Rosenstark

    6. Oktober 2014 um 23:43 Uhr

  • @Yar hat meinen Kommentar ein wenig erweitert und wie gewünscht eine neue Antwort hinzugefügt

    – Jo

    7. Oktober 2014 um 7:17 Uhr

  • Wenn bekannte Bits für Informationen verwendet werden (dh für Netzwerkprotokolle wie Websockets), werden die Daten auf a struct kann auch nützlich sein, da Sie alle erforderlichen Daten mit einem einzigen Vorgang erhalten.

    – Myst

    29. Dezember 2015 um 6:34 Uhr

  • @forefinger, kannst du bitte eine Beispielausgabe des Codes posten.

    – Kiste Kiste Kiste Kiste

    9. Januar 2016 um 3:36 Uhr

Joes Benutzeravatar
Jo

Wie gewünscht habe ich beschlossen, meinen Kommentar zur Antwort des Zeigefingers auf eine vollständige Antwort zu erweitern. Obwohl seine Antwort richtig ist, ist sie unnötig komplex. Außerdem verwenden alle aktuellen Antworten signiert ints zur Darstellung der Werte. Dies ist gefährlich, da die Rechtsverschiebung negativer Werte implementierungsdefiniert (dh nicht portierbar) ist und die Linksverschiebung zu undefiniertem Verhalten führen kann (siehe diese Frage).

Durch Verschieben des gewünschten Bits nach rechts in die Position des niederwertigsten Bits kann eine Maskierung durchgeführt werden 1. Es ist nicht erforderlich, für jedes Bit einen neuen Maskenwert zu berechnen.

(n >> k) & 1

Als vollständiges Programm, das ein Array von Einzelbitwerten berechnet (und anschließend druckt):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    unsigned
        input = 0b0111u,
        n_bits = 4u,
        *bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
        bit = 0;

    for(bit = 0; bit < n_bits; ++bit)
        bits[bit] = (input >> bit) & 1;

    for(bit = n_bits; bit--;)
        printf("%u", bits[bit]);
    printf("\n");

    free(bits);
}

Unter der Annahme, dass Sie wie in diesem Fall alle Bits berechnen möchten und nicht ein bestimmtes, kann die Schleife weiter geändert werden

for(bit = 0; bit < n_bits; ++bit, input >>= 1)
    bits[bit] = input & 1;

Dies modifiziert input vorhanden und ermöglicht dadurch die Verwendung einer Einzelbitverschiebung mit konstanter Breite, die bei einigen Architekturen effizienter sein kann.

wallyks Benutzeravatar
Wallyk

Hier ist eine Möglichkeit, es zu tun – es gibt viele andere:

bool b[4];
int v = 7;  // number to dissect

for (int j = 0;  j < 4;  ++j)
   b [j] =  0 != (v & (1 << j));

Es ist schwer zu verstehen, warum die Verwendung einer Schleife nicht erwünscht ist, aber es ist einfach genug, die Schleife abzuwickeln:

bool b[4];
int v = 7;  // number to dissect

b [0] =  0 != (v & (1 << 0));
b [1] =  0 != (v & (1 << 1));
b [2] =  0 != (v & (1 << 2));
b [3] =  0 != (v & (1 << 3));

Oder konstante Ausdrücke in den letzten vier Anweisungen auswerten:

b [0] =  0 != (v & 1);
b [1] =  0 != (v & 2);
b [2] =  0 != (v & 4);
b [3] =  0 != (v & 8);

Benutzeravatar von d3vdpro
d3vdpro

Hier ist ein sehr einfacher Weg, es zu tun;

int main()
{
    int s=7,l=1;
    vector <bool> v;
    v.clear();
    while (l <= 4)
    {
        v.push_back(s%2);
        s /= 2;
        l++;
    }
    for (l=(v.size()-1); l >= 0; l--)
    {
        cout<<v[l]<<" ";
    }
    return 0;
}

Verwenden std::bitset

int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();

  • Es ist eine nützliche Methode, aber im Beispiel stimmt etwas nicht. bitset, n ist die Anzahl der Bits, daher ist die Verwendung von sizeof(int) falsch.

    – Jerry Chou

    15. April 2019 um 6:09 Uhr

Benutzeravatar von xinthose
xinthose

@prateek Danke für deine Hilfe. Ich habe die Funktion mit Kommentaren für die Verwendung in einem Programm umgeschrieben. Erhöhen Sie 8 für mehr Bits (bis zu 32 für eine Ganzzahl).

std::vector <bool> bits_from_int (int integer)    // discern which bits of PLC codes are true
{
    std::vector <bool> bool_bits;

    // continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
    for (int i = 0; i < 8; i++)
    {
        bool_bits.push_back (integer%2);    // remainder of dividing by 2
        integer /= 2;    // integer equals itself divided by 2
    }

    return bool_bits;
}

  • Es ist eine nützliche Methode, aber im Beispiel stimmt etwas nicht. bitset, n ist die Anzahl der Bits, daher ist die Verwendung von sizeof(int) falsch.

    – Jerry Chou

    15. April 2019 um 6:09 Uhr

#include <stdio.h>

int main(void)
{
    int number = 7; /* signed */
    int vbool[8 * sizeof(int)];
    int i;
        for (i = 0; i < 8 * sizeof(int); i++)
        {
            vbool[i] = number<<i < 0;   
            printf("%d", vbool[i]);
        }
    return 0;
}

1423060cookie-checkWie erhalte ich Bit-für-Bit-Daten von einem ganzzahligen Wert in C?

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

Privacy policy