Go Down

Topic: Datentypen und Verwendung von Funktionen zur Manipulation von Bits in int/long (Read 598 times) previous topic - next topic

dischneider

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-(a*256); // 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

using arduino leonardo
--
tomorrow today will only be yesterday, so live your life today!

markbee

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?
XBee blog: http://lookmanowire.blogspot.com/

J3RE

Du könntest es mit Bitmasken probieren z.B. so:
Code: [Select]
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

dischneider

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

using arduino leonardo
--
tomorrow today will only be yesterday, so live your life today!

michael_x

0xF
0x0F
0x000F

sind alles dieselben Konstanten.

Quote
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.



jurs


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:

Code: [Select]

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

dischneider

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
using arduino leonardo
--
tomorrow today will only be yesterday, so live your life today!

Go Up