Erfassen von n Bits aus einem Byte

Lesezeit: 4 Minuten

Benutzer-Avatar
Benutzer1871869

Ich habe ein wenig Probleme beim Erfassen von n Bits aus einem Byte.

Ich habe eine Ganzzahl ohne Vorzeichen. Nehmen wir an, unsere Zahl in Hex ist 0x2A, was 42 in Dezimalzahl ist. Im Binärformat sieht es so aus: 0010 1010. Wie würde ich die ersten 5 Bits, die 00101 sind, und die nächsten 3 Bits, die 010 sind, greifen und sie in separate Ganzzahlen einfügen?

Wenn mir jemand helfen könnte wäre das super! Ich weiß, wie man aus einem Byte extrahiert, was einfach zu tun ist

int x = (number >> (8*n)) & 0xff // n being the # byte

was ich in einem anderen Beitrag zum Stapelüberlauf gesehen habe, aber ich war mir nicht sicher, wie ich einzelne Bits aus dem Byte herausbekomme. Wenn mir jemand weiterhelfen könnte, wäre das super! Vielen Dank!

  • Die ersten 5 (MSB) Bits von 42 sind 00000, da int immer größer als 1 Byte ist. Außerdem gibt es keine vorzeichenlose Ganzzahl, die die Dezimalform eines Hexadezimalzeichens hat. int a = 0x2A; ist das gleiche wie schreiben int a = 42;

    – Benutzer93353

    6. März 2013 um 19:06 Uhr


Benutzer-Avatar
rici

Ganze Zahlen werden innerhalb einer Maschine als Folge von Bits dargestellt; Zum Glück für uns Menschen bieten Programmiersprachen einen Mechanismus, um uns diese Zahlen dezimal (oder hexadezimal) anzuzeigen, aber das ändert nichts an ihrer internen Darstellung.

Sie sollten die bitweisen Operatoren überprüfen &, |, ^ und ~ sowie die Schichtbetreiber << und >>die Ihnen helfen, zu verstehen, wie Sie solche Probleme lösen können.

Die letzten 3 Bits der Ganzzahl sind:

x & 0x7

Die fünf Bits beginnend mit dem achtletzten Bit sind:

x >> 3    // all but the last three bits
  &  0x1F // the last five bits.

  • Wie verhält sich dies leistungsmäßig mit dem einfachen Speichern der beiden Sub-Ints als zwei 32-Bit-Ganzzahlen? Das Extrahieren wird einige Zeit dauern, aber ist es 32 Operationen langsamer?

    – Kammeot

    16. Oktober 2014 um 16:58 Uhr

  • @InspiredOne: Fragen wie diese können abstrakt nicht genau beantwortet werden, aber es ist offensichtlich, dass sie die Speichernutzung verbessern (um den Faktor acht relativ zu zwei 32-Bit-Ganzzahlen oder um den Faktor zwei relativ zu zwei Bytes), was sich verbessert Cache-Leistung, Speicherdurchsatz und ggf. Bandbreite (Übertragungszeit oder Sekundärspeicher). Da die CPU-Kosten im Vergleich zu diesen Faktoren trivial sind, werden die komprimierten Daten normalerweise schneller sein, vorausgesetzt, Sie benötigen viele Instanzen; Es lohnt sich nicht, dies für ein einzelnes Variablenpaar zu tun (aber es tut auch nicht viel weh).

    – Rici

    16. Oktober 2014 um 20:36 Uhr


Benutzer-Avatar
Matt Petersson

Das “Ergreifen” von Teilen eines Integer-Typs in C funktioniert folgendermaßen:

  1. Sie verschieben die gewünschten Bits auf die niedrigste Position.
  2. Sie nutzen & um die gewünschten Bits zu maskieren – Einsen bedeuten “dieses Bit kopieren”, Nullen bedeuten “ignorieren”

Also in deinem Beispiel. Nehmen wir an, wir haben eine Nummer int x = 42;

erste 5 Bit:

(x >> 3) & ((1 << 5)-1);

oder

(x >> 3) & 31;

So rufen Sie die unteren drei Bits ab:

(x >> 0) & ((1 << 3)-1)

oder:

x & 7;

Benutzer-Avatar
gaborsch

Sagen Sie, Sie wollen hi Bits von oben, und lo Bits von unten. (5 und 3 in Ihrem Beispiel)

top = (n >> lo) & ((1 << hi) - 1)
bottom = n & ((1 << lo) - 1)

Erläuterung:

Für die obenentfernen Sie zuerst die unteren Bits (nach rechts verschieben) und maskieren Sie dann die verbleibenden mit einer “Alles-Einsen” -Maske (wenn Sie eine Binärzahl wie z 0010000Subtrahieren von eins ergibt 0001111 – die gleiche Anzahl von 1ist wie du hattest 0-s in der Originalnummer).

Für den Boden ist es dasselbe, Sie müssen sich nur nicht um das anfängliche Schalten kümmern.

top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b

Sie könnten dafür Bitfelder verwenden. Bitfelder sind spezielle Strukturen, in denen Sie Variablen in Bits angeben können.

typedef struct {
  unsigned char a:5;
  unsigned char b:3;
} my_bit_t;

unsigned char c = 0x42;
my_bit_t * n = &c;
int first = n->a;
int sec = n->b;

Bitfelder werden detaillierter unter beschrieben http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

Der Charme von Bitfeldern ist, dass man sich nicht mit Schiebeoperatoren etc. auseinandersetzen muss. Die Notation ist recht einfach. Wie immer bei der Manipulation von Bits gibt es ein Portabilitätsproblem.

int x = (number >> 3) & 0x1f;

gibt Ihnen eine Ganzzahl, bei der die letzten 5 Bits die 8-4 Bits von sind number und Nullen in den anderen Bits.

Ähnlich,

int y = number & 0x7;

gibt Ihnen eine Ganzzahl mit den letzten 3 Bits, die die letzten 3 Bits von setzen number und die Nullen im Rest.

Benutzer-Avatar
David

Entfernen Sie einfach die 8* in Ihrem Code.

int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)

1353720cookie-checkErfassen von n Bits aus einem Byte

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

Privacy policy