Go Down

Topic: Unsigned Long Überlauf (Read 737 times) previous topic - next topic

Metti

Hallo,

ich habe viele Werte, die ich aneinander reihen möchte. Leider ist auch ein unsigned long zu kurz dafür.
Gibt es irgendeine Überlauffunktion? Praktisch soetwas wie ein Schieberegister für Bits?

Ein Beispiel:
Angenommen ich habe folgende Werte:

1001   100101   11   101110   1011

Und will ich sie so speichern:

byte meinbyte = ((((((((1001 << 6) + 100101) << 2) + 11) << 6) + 101110) << 4) + 1011)

Natürlich passen nicht alle in ein Byte und es würden alle, bis auf die letzten acht verloren gehen.
Gibt es eine Funktion, die die Bits, die vorne rausfallen würden auffängt und in ein anderes Byte schreibt?

Vielen Dank für eure Hilfe Metti

jurs

#1
Dec 20, 2012, 07:31 pm Last Edit: Dec 20, 2012, 07:35 pm by jurs Reason: 1

Angenommen ich habe folgende Werte:

1001   100101   11   101110   1011


Ich zähle mal durch: 22 Bits


Und will ich sie so speichern:

byte meinbyte = ((((((((1001 << 6) + 100101) << 2) + 11) << 6) + 101110) << 4) + 1011)

Natürlich passen nicht alle in ein Byte und es würden alle, bis auf die letzten acht verloren gehen.


byte ==> 8 Bit
int ==> 16 Bit
long ==> 32 Bit

Nimmst Du eben einen Variablentyp, der groß genug ist, und shiftest Deine Bits da rein.
Ein "byte" ist zu klein, ein "long" nicht.

Statt "byte" also "unsigned long", dann reicht es für 32 Bits.

P.S.: Und wenn Du von Bits sprichst, dann wirst Du vermutlich Binärzahlen in Deine Variable reinschieben wollen und keine Dezimalzahlen so wie in Deinem Codebeispiel.

Metti

#2
Dec 20, 2012, 09:06 pm Last Edit: Dec 20, 2012, 09:08 pm by Metti Reason: 1
Wie schon geschrieben handelt es sich bei den Bytes um ein Beispiel um das Prinzip zu verdeutlichen, weil ich es euch ersparen wollte hier nun 384 Bits hintereinander wegzuschreiben.

Tatsächlich handelt es sich um Informationen, jeweils 1-5 Bit, die hintereinander zusammengesetzt bis zu 48 Byte ergeben können. Die hätte ich gerne in einem Stück, zwangsläufig werde ich sie also nun aufteilen müssen.

Natürlich könnte ich sie umständlich in einem Array unterbringen:

Array2 aufschieben
Erstes Bit von Array1 in Array2 schreiben,
Array1 aufschieben
Neues Bit auslesen und ins erste Bit von Array1 schreiben
Das nun für 12 Arrays...

Im Code wird es aber leider recht kompliziert, weil dann jedes Bit einzeln reingenommen werden muss (bitWrite()).


Quote
P.S.: Und wenn Du von Bits sprichst, dann wirst Du vermutlich Binärzahlen in Deine Variable reinschieben wollen und keine Dezimalzahlen so wie in Deinem Codebeispiel.


Versteh ich nich :-/

jurs

#3
Dec 20, 2012, 09:24 pm Last Edit: Dec 20, 2012, 09:30 pm by jurs Reason: 1

Tatsächlich handelt es sich um Informationen, jeweils 1-5 Bit, die hintereinander zusammengesetzt bis zu 48 Byte ergeben können. Die hätte ich gerne in einem Stück, zwangsläufig werde ich sie also nun aufteilen müssen.


Ach so. Dein Beispiel hatte ich durchgezählt und bin dabei auf 22 Bits gekommen.
Dann hätten ja 32-Bit Variablen gereicht.

Wenn es bis zu 48 Bits hast, dann nimmst Du eben einen noch längeren Datentyp: "long long".

Eine "long long" Variable hat 64 Bits (8 Bytes am Stück).

Eine solche Variable hat den Vorteil, dass Du alle Bits am Stück hast, inklusive aller möglichen Bitschiebeoperationen. Allerdings gibt es den Nachteil, dass Du Dir Funktionen zum Ausgeben solcher Variablen (Binär, Dezimal oder wie auch immer) dann selbst schreiben müßtest, weil Arduino für "long long" keinerlei Umwandlungsroutinen in Strings mehr zur Verfügung stellt.


Versteh ich nich :-/


Eine Rechenoperation wie "+ 100101" addiert die Dezimalzahl 100101 ("Hunderttausendeinhundertundeins") zum Zwischenergebnis dazu und nicht die möglicherweise beabsichtigte Binärzahl mit diesem Bit-Muster.

Metti

Long Long? Da bin ich bisher nicht drauf gekommen, ich habe bisher nur mit den Datentypen von der Reference-Seite gearbeitet.

Wenn es noch längere Datentypen gäbe würde das ziemlich helfen, denn ich brauche bis zu 48 Byte, nicht Bit :-/

Quote
Eine Rechenoperation wie "+ 100101" addiert die Dezimalzahl 100101 ("Hunderttausendeinhundertundeins") zum Zwischenergebnis dazu und nicht die möglicherweise beabsichtigte Binärzahl mit diesem Bit-Muster.


Stimmt, ich meinte natürlich Binärzahlen, eben 0b100101 etc.

uwefed

48 Byte?
Da bleibt Dir nichts anderes übrig als ein Array zu verwenden.
Grüße Uwe

michael_x

#6
Dec 21, 2012, 09:45 am Last Edit: Dec 21, 2012, 12:28 pm by michael_x Reason: 1

48 Byte?
Da bleibt Dir nichts anderes übrig als ein Array zu verwenden.

Oder eine struct.

Die kann man sogar mit Elementen kleiner als 8 bit definieren.

Ein (sinnloses) Beispiel
Code: [Select]

struct MYDATA {
unsigned head:5;  // 5 bit
unsigned a:1;       // 1 bit
unsigned b:2;       // 2 bit
byte c;
byte d;
byte rest[45];
};

MYDATA buffer;

void setup() {
buffer.head = 0b10001;
buffer.a = 0;
buffer.b = 3;
}
void loop() {}

(Edit : Compilerfehlerfrei, aber immer noch sinnlos)

Eventuell noch in einer union alternativ als  byte array[48] definieren , je nach dem wie/wofür es gebraucht wird

jurs


Wenn es noch längere Datentypen gäbe würde das ziemlich helfen, denn ich brauche bis zu 48 Byte, nicht Bit :-/


Ne, bei long long mit 64 Bit ist Schluss.
Danach mußt Du selber coden.

Wenn Du mehrere Hundert Bits benötigst, dann nimmst Du am besten ein Array of Byte in der entsprechenden Größe und schreibst Dir Funktionen zum Setzen und Löschen einzelner Bits in dem Array. Wenn dann das Bitmuster 0b10001 für die Bits 141 bis 146 gesetzt werden sollst, rufst Du bei Dir dann jeweils abhängig ob eine 1 oder eine 0 gesetzt werden soll auf:
setBit(141); ==> Setzt das Bit an 141. Stelle im Array
clearBit(142); ==> Löscht das Bit an 142. Stelle im Array
result=testBit(141); ==> Liefert 0 oder eins beim Abfragen des Bits, je nachdem ob Bit gesetzt oder nicht

Mit drei Funktionen wie setBit, clearBit und testBit kannst Du schon diverses machen. Wenn Du Bits auch einfach drehen möchtest, schreibst Du Dir vielleicht auch noch eine swapBit-Funktion (dreht 0 in 1 bzw 1 in 0), wenn Du das ganze Array mit einem Befehl löschen möchtest schreibst Du eine Funktion clearAllBits (löscht alle Bits im Array) oder was Du sonst noch brauchst.

Go Up