Datentypen und Verwendung von Funktionen zur Manipulation von Bits in int/long

Hallo alle,

ich habe hier eine Variable x (sei sie u_long, u_int oder was auch immer), die genau 12 Bit mit Werten hat, alle höherwertigen sind "0", also habe ich einen Wert 0-4095.
Diese 12 Bit sind genau genommen 3x 4 Bit, die ich dann separat weiter verarbeiten möchte / muss.
Jetzt könnte ich natürlich mit mathematischen Operationen da ran gehen und das aufdröseln:

byte a;
byte b;
byte c;
a = x/256; // Wert der 4 höchsten Bit
x = x-(a256); // Es bleiben nur noch 8 Bit übrig
b = x/64; // Wert der "mittleren" 4 Bit
c = x-(b
64); // Wert der niedrigen 4 Bit

Setzen kann man ja mit

byte d = B00101010;

und ausgeben mit

print(d, BIN);

Daraus stellt sich mir die Frage, ob ich nicht auch anders auf die jeweiligen Daten zugreifen kann, um das Ganze etwas eleganter und "sauberer" zu lösen?
Das wäre dann auch nett, wenn man in einer Variable den "Schaltzustand" mehrere Parameter ablegen möchte.

Danke

Dirk

Du kannst doch mit bitweise & die einzelnen nibbles maskieren und so die drei 4-bit-Werte recht einfach herausbekommen. Oder habe ich dich falsch verstanden?

Du könntest es mit Bitmasken probieren z.B. so:

a = (x & 0x00F); // 0x00F entspricht 0000 0000 1111 also die 4 niederwertigsten Bits sind 1, dadurch werden höherwertige Bits "weckgeschnitten"
b = ((x >> 4) & 0x00F);
c = ((x >> 8) & 0x00F);

Grüße,
J3RE

Hi und danke für die Antwort.
Stimmt, bitshift ist eine Idee.
Aber die Maske ist mir noch unklar.
wenn ich 0101 1010 0011 habe ergibt "& 0x00F" richtig "0011" -> wenn das in eine "Byte"-Variable geht sind die nicht gesetzten Stellen automatisch "0" oder werden sie nur nicht verändert, muss ich also "byte a" zuvor wieder "a = 0" resetten?

Und wenn die Maske kürzer ist als die Variable, ist das egal? Bei u_int habe ich ja je nach Prozessor 16 bzw. 32 bit, bei u_long sowieso 32.
Müsste ich dann nicht "0x000F" oder "0x0000000F" nehmen?

Danke

Dirk

0xF
0x0F
0x000F

sind alles dieselben Konstanten.

wenn ich 0101 1010 0011 habe ergibt "& 0x00F" richtig "0011" -> wenn das in eine "Byte"-Variable geht sind die nicht gesetzten Stellen automatisch "0" oder werden sie nur nicht verändert, muss ich also "byte a" zuvor wieder "a = 0" resetten?

Wenn du a als byte definierst, hat es 8 Bit und die Zuweisung a = x & 0x00F; // verändert alle 8 bit
egal was vorher drin stand.

Wenn du nur einzelne Bytes eines int oder long manipulieren wolltest, müsstest du besondere Klimmzüge machen.

dischneider:
Und wenn die Maske kürzer ist als die Variable, ist das egal? Bei u_int habe ich ja je nach Prozessor 16 bzw. 32 bit, bei u_long sowieso 32.
Müsste ich dann nicht "0x000F" oder "0x0000000F" nehmen?

Führende Nullen bei Zahlen sind egal. Bei Dezimalschreibweise genauso wie bei Binär- oder Hexschreibweise.

Wenn ich vier Bits maskieren möchte, dann schreibe ich auch vier Bits hin:

  long gesamt=0b110010000001;
  byte nibbles[3];
  nibbles[0]= (gesamt >>8) & 0b1111;
  nibbles[1]= (gesamt >>4) & 0b1111;
  nibbles[2]= gesamt & 0b1111;

Ah OK, dann hab ich das jetzt verstanden, prima.
Ich war mir nicht sicher, ob die Maskierung, ähnlich einer Netmask, komplett sein sollte, also alle Stellen mit “0” oder “1” in Form von “nicht nutzen” oder “nutzen” angegeben werden müssen. Aber jetzt hab ich das begriffen, fein, ich danke für eure Hilfe.

Dirk