Bits aus einem Feld extrahieren
-
Hallo!
Ich habe ein Bitfeld von dem ich das zu extrahierende Bit und den Wert des Feldes kenne. Mein Problem ist nur, das es von links nach rechts verläuft:
1 2 3 4 5 6 7 8
1 0 0 1 1 0 0 0Wie schon gesagt ich kenne das Byte. In diesem Beispiel 0x98 und die zu extrahierende Stelle z.B. die 4.. Wie kann ich jetzt wissen ob da 0 oder 1 steht?
Danke!
-
würd ich spontan so machen,
#include <stdio.h> int main() { int x=0x98; int i=4; //diese stelle willst du wissen if ( x>>(8-i)&0x1 ) printf("is gesetzt\n"); else printf("is nich gesetzt\n"); return 0; }
geht aber bestimmt eleganter
b4sh0r
-
du KÖNNTEST in ein Binär-array umwandeln.
speicherplatz ist doch nicht so wichtig oder?
(boolmfG (c)h
-
Danke, dass funktioniert sehr gut.
Bleibt jedoch noch eine Möglichkeit die ich vorher nicht bemerkt hatte:
Das Feld kann auch eine "ungerade" Bitzahl haben.
Damit meine ich folgendes:1 2 3 4 5 6 7 8 9
1 0 0 1 1 0 0 0 1
0x98 0x01Mit den Bits 1-8 funktioniert es.
Der Wert des 2. Bytes ist 0x01. Es ist also nicht auf ein volles Byte geshiftet.
Wende ich nun x >> (8-i) an wird das Ergebnis falsch sein. Irgendwie müsste ich testen, ob das Byte vollständig ist. Und wenn nicht nur die verbleibenden Bytes shiften.
Falls es hilft: Die Größe des Feldes (Anzahl der Bits) ist bekannt. Hier wäre sie ja 9.
-
Na wenn du die Länge weißt, dann kannst du sie ja einsetzen anstatt der festen 8.
-
Das funktioniert ja aber doch nur so lange wie mein x in ein 32Bit Register passt, also long ist. Wenn das Feld aber größer, eher sehr größer ist dann shifte ich ja vielleicht um 100. Und dann funktioniert es auch nicht.
Kann ich vielleicht irgendwie mit Pointern arbeiten?
-
da erscheint mir die idee mit dem binär-array schon ganz sinnvoll, das kannst du an deine größe anpassen. die frage ist nur, wie du das umwandelst...kommt halt auf deine werte an.
-
Ich benutze für meine 'Bitfelder' immer ein normales Array. Bsp:
int Feld[4];
Das ist dann ein 'Bitfeld' mit 128 Bits. Wenn Du jetzt beispielsweise Bit 45 anschauen willst :
bool t = ( Feld[(int)(45/31)] >> (45 % 32) ) & 0x1);
Vielleicht hilft Dir das ja..
//EDIT: vielleicht sollte ich noch anmerken, dass ich die Bits umgekehrt speichere; Bit 0 rechts. Bei Dir fehlt dann noch ein 32-...
Gruß
Michael
-
atzplzw schrieb:
Das funktioniert ja aber doch nur so lange wie mein x in ein 32Bit Register passt, also long ist. Wenn das Feld aber größer, eher sehr größer ist dann shifte ich ja vielleicht um 100. Und dann funktioniert es auch nicht.
Kann ich vielleicht irgendwie mit Pointern arbeiten?
Wie bekommst du deine Bits überhaupt angeliefert??
-
Sie kommen in Form von Bytes variabler Länge. Da ich sie nicht mache, sondern nur aus einer Datei auslese kann ich leider an der Erstellung nix ändern.
for (;;) { x = BitItem; if (x == NULL) { if (numberOfBitsInBuffer > 0) Write(&bitBuffer); break; } if (x.BitSet) { bitBuffer |= (1 << numberOfBitsInBuffer); } ++numberOfBitsInBuffer; if (numberOfBitsInBuffer == 8) { Write(&bitBuffer); bitBuffer = 0; numberOfBitsInBuffer = 0; } }
-
Da haben wir ja schon den Knackpunkt. Wenn du die Bits aus einer Datei liest, dann kannst du sie ja gleich in ein Char-Array einlesen und die Sache ist gegessen.
-
Wie soll das gehen?
-
atzplzw schrieb:
Wie soll das gehen?
Datei:
00111001000011001
Einlesen:
... FILE * fp; char buffer[256]; ... fp = fopen("bits.dat", "r"); if(fp) { fgets(buffer, 256, fp); fclose(fp); } ...
In Buffer stehen nun deine 0en und 1en:
buffer[0] == 0 buffer[1] == 0 buffer[2] == 1 ...
-
AJ schrieb:
In Buffer stehen nun deine 0en und 1en:
buffer[0] == 0 buffer[1] == 0 buffer[2] == 1 ...
Stehen dann nicht im buffer[0] == 00111001, also das erste byte der datei?
-
Man kann keine einzelnen Bits adressieren - deshalb kapiere ich nicht, wo hier das Problem ist.
Es ist technisch ja nicht möglich nur ein halbes Byte aus einer Datei zu lesen (oder auch zu schreiben). Deshalb hat man die Bits doch immer auf ein Byte aligned...
-
/bin/bash0R schrieb:
AJ schrieb:
In Buffer stehen nun deine 0en und 1en:
buffer[0] == 0 buffer[1] == 0 buffer[2] == 1 ...
Stehen dann nicht im buffer[0] == 00111001, also das erste byte der datei?
Genau das meine ich doch auch!