Hallo,
ich habe ein Byte (hier Var) und möchte aufgrund der gesetzten Bits eine
Zahl (hier Zahl) "bestrafen".
Hier z.B. ein Byte
1
unsigned char Var=0b101000;
2
// Var=10|10|00
Und hier nun die Logik:
Zahl=0;
1. Paket (Bits 1&2 ):
Wenn die ersten beiden Bits 00, dann Zahl=Zahl+1;
Wenn die ersten beiden Bits 10, dann Zahl=Zahl+2;
2. Paket (Bits 3&4):
Wenn die zweiten beiden Bits 00, dann Zahl=Zahl+1;
Wenn die zweiten beiden Bits 10, dann Zahl=Zahl+2;
usw.
Bei dem Beispiel müsste die "Zahl" dann den Wert 5 aufweisen.
Wie kann man so etwas auf einem uController am effektivsten realisieren,
ohne große If abfragen?
Grüße
Unwissender69 schrieb:> Wenn die ersten beiden Bits 00, dann Zahl=Zahl+1;> Wenn die ersten beiden Bits 10, dann Zahl=Zahl+2;
uint8_t result = 0;
if(var & (1 << 6))
result |= ((var >> 1) + (1 << 6)) & ((1 << 6) | (1 << 7));
Unwissender69 schrieb:> Wenn die zweiten beiden Bits 00, dann Zahl=Zahl+1;> Wenn die zweiten beiden Bits 10, dann Zahl=Zahl+2;
if(var & (1 << 4))
result |= ((var >> 1) + (1 << 4)) & ((1 << 4) | (1 << 5));
Unwissender69 schrieb:> Bei dem Beispiel müsste die "Zahl" dann den Wert 5 aufweisen.> Wie kann man so etwas auf einem uController am effektivsten realisieren,> ohne große If abfragen?
Ganz ohne würde ich es nicht machen. Aber eine pro Paket ist ja nicht so
schlimm.
Dankeschön Samuel,
das dauert mir zu lange bei 20 Variablen. Der uC ist ja nur mit schieben
beschäftigt.
Werde es in den Speicher legen und geeignet darauf zugreifen.
Viele Grüße
Unwissender69 schrieb:> Dankeschön Samuel,> das dauert mir zu lange bei 20 Variablen. Der uC ist ja nur mit schieben> beschäftigt.
Warum denn? Nur einmal pro Rechnung. Und wenn man diese Var >> 1
temporär speichert ist es nur einmal schieben.
Die (1 << 4) werden vom Compiler ersetzt.
> Werde es in den Speicher legen und geeignet darauf zugreifen.
Oder meinst du das damit?
Sollen wie im Beispiel immer nur 3 Bitpaare (also die Bits 0 bis 5)
betrachtet werden?
Oder was soll bspw. mit Var=0b10101000 passieren?
Nur aus Neugier: Warum bezeichnest du das Addieren von 1 oder 2 als
"bestrafen"?
Was meinst du mit am "effektivsten"?
Unabhängig davon: Eine sehr schnelle Methode wäre eine Tabelle (Array)
mit 256 Einträgen, von denen jeder das gesamte "Strafmaß" für das
entsprechende Byte enthält.
Ich merke gerade, dass man die if-Abfrage negieren muss.
Und wenn ich schon dabei bin. Ein bisschen optimierter:
uint8_t result = 0, x = (1 << 6), y = (1 << 6) | (1 << 7);
uint8_t varl1 = var >> 1;
do
{
if(!(var & x))
result |= (varl1 + x) & y;
x = x >> 2;
y = y >> 2;
}
while(x);
Oder in einer Anweisung:
#define mask 0b01010101
var = !(var & mask) * ((var >> 1) & mask + 1);
Ich gebe aber keine Garantie, dass das funktioniert.
Mir fällt gerade auf: Deine Idee funktioniert gar nicht: 0b10 + 2 ergibt
einen überlauf.
Stefan schrieb:> Hat dein Byte nur 6 Bit?
Ja, die restlichen Bits werden nicht betrachtet.
Stefan schrieb:> Können die Bitkombinationen 01 und 11 nicht auftreten?
01 kann auftreten, ist aber ein don't care und 11 tritt nicht auf.
Yalu X. schrieb:> Sollen wie im Beispiel immer nur 3 Bitpaare (also die Bits 0 bis 5)> betrachtet werden?
Ja, es sollen nur 3 Bit-Paare verglichen werden.
Yalu X. schrieb:> soll bspw. mit Var=0b10101000 passieren?
don't care! Nur die ersten 6 bits, und auch da nur paarweise.
Yalu X. schrieb:> Nur aus Neugier: Warum bezeichnest du das Addieren von 1 oder 2 als> "bestrafen"?
Weil damit bestimmte Zustände in einem Algorithmus "bestraft" werden
sollen. Dies bedeutet, je höher die Zahl ist umso unwahrscheinlicher
wird dieser Zustand. Die Zustände sind einschrittig Kodiert.
Yalu X. schrieb:> Eine sehr schnelle Methode wäre eine Tabelle (Array)> mit 256 Einträgen, von denen jeder das gesamte "Strafmaß" für das> entsprechende Byte enthält.
So hatte ich es vor. Da einige Berechnungen durchgeführt werden, möchte
ich den Overhead, z.B. für Bitoperationen, so klein als möglich halten.
Yalu X. schrieb:> Was meinst du mit am "effektivsten"?
Schnelle Abarbeitungszeit.
Jobst M. schrieb:> ... und wo kommt da nun 5 heraus?
sry, ich habe es falsch verstanden. Ich dachte die Zahl soll dem PAket
dazugerechnet werden.
Ok noch mal überlegen.