Forum: Compiler & IDEs C Logikproblem


von Michael M. (mj09)


Lesenswert?

Hallo Zusammen,
ich betreibe meine Jalousinsteuerung mit dem Raspberry PI.
Läuft super.

Nun möchte ich meine Steuerung erweitern und habe ein Logikproblem.
Ich habe mal eine Tabelle erstellt um das Problem zu erläutern.
1
4  3  2  1        8  4  2  1  8  4  2  1  
2
0  0  0  0  0x00  0  0  0  0  0  0  0  0  0x00
3
0  0  0  1  0x01  0  0  0  0  0  0  1  1  0x03
4
0  0  1  0  0x02  0  0  0  0  1  1  0  0  0x0C
5
0  0  1  1  0x03  0  0  0  0  1  1  1  1  0x0F
6
0  1  0  0  0x04  0  0  1  1  0  0  0  0  0x30
7
0  1  0  1  0x05  0  0  1  1  0  0  1  1  0x33
8
0  1  1  0  0x06  0  0  1  1  1  1  0  0  0x3C
9
0  1  1  1  0x07  0  0  1  1  1  1  1  1  0x3F
10
1  0  0  0  0x08  1  1  0  0  0  0  0  0  0xC0
11
1  0  0  1  0x09  1  1  0  0  0  0  1  1  0xC3
12
1  0  1  0  0x0A  1  1  0  0  1  1  0  0  0xCC
13
1  0  1  1  0x0B  1  1  0  0  1  1  1  1  0xCF
14
1  1  0  0  0x0C  1  1  1  1  0  0  0  0  0xF0
15
1  1  0  1  0x0D  1  1  1  1  0  0  1  1  0xF3
16
1  1  1  0  0x0E  1  1  1  1  1  1  0  0  0xFC
17
1  1  1  1  0x0F  1  1  1  1  1  1  1  1  0xFF
Auf der linken Seite habe ich 4 Eingangswerte. Die rechte Seite zeigt 
den Ausgangswert.
Ich könnte nun diverse If-Abfragen schreiben und das Problem wäre 
gelöst.
Finde ich aber nicht so gut.
Ich komme auf keine Logik, die mir diese Werte liefert.
Eventuell hat jemand von euch eine Lösung für mich.

Viele Grüße

Michael

von Bastler (Gast)


Lesenswert?

Array aus 16 Byte-Werten?

von N. G. (newgeneration) Benutzerseite


Lesenswert?

ich weiß nicht, ob es dir hilft, aber schau dir mal die Bits an.
1
8  4  2  1  8  4  2  1
2
0  0  0  0  0  0  0  0  0x00
3
0  0  0  0  0  0  1  1  0x03
4
0  0  0  0  1  1  0  0  0x0C
5
0  0  0  0  1  1  1  1  0x0F
6
0  0  1  1  0  0  0  0  0x30
7
0  0  1  1  0  0  1  1  0x33
8
0  0  1  1  1  1  0  0  0x3C
9
0  0  1  1  1  1  1  1  0x3F
10
1  1  0  0  0  0  0  0  0xC0
11
1  1  0  0  0  0  1  1  0xC3
12
1  1  0  0  1  1  0  0  0xCC
13
1  1  0  0  1  1  1  1  0xCF
14
1  1  1  1  0  0  0  0  0xF0
15
1  1  1  1  0  0  1  1  0xF3
16
1  1  1  1  1  1  0  0  0xFC
17
1  1  1  1  1  1  1  1  0xFF
18
----------------------------
19
^  ^  ^  ^  ^  ^  ^  ^
20
|  |  |  |  |  |  |  |
21
+--+  +--+  +--+  +--+  
22
die werden konstant invertiert
23
und immer 2 gleiche

von Peter II (Gast)


Lesenswert?

sind doch nur 4 IFs
1
out = 0;
2
if ( in & 1 ) 
3
   out |= 3
4
5
if ( in & 2 ) 
6
   out |= (3<<2)
7
8
if ( in & 4 ) 
9
   out |= (3<<4)
10
11
if ( in & 8 ) 
12
   out |= (3<<6)

von lulu (Gast)


Lesenswert?

Keine If, nur viel Rechnen
1
out = (in&0x08)*0xC0 + (in&0x04)*0x30 + (in&0x02)*0x0C + (in&0x01)*0x03

von lulu (Gast)


Lesenswert?

optimiert:
1
out = (in&0x08)*0xC0 | (in&0x04)*0x30 | (in&0x02)*0x0C | (in&0x01)*0x03

von lulu (Gast)


Lesenswert?

sorry Fehler:
1
out = (in&0x08)*0x18 | (in&0x04)*0x0C | (in&0x02)*0x06 | (in&0x01)*0x03

von Dirk B. (dirkb2)


Lesenswert?

Bastler schrieb:
> Array aus 16 Byte-Werten?

Ohne Fragezeichen!

von Amateur (Gast)


Lesenswert?

Ein Array würde das Problem am schnellsten und übersichtlichsten lösen.
Ansätze wie die von Peter sind wohl eleganter, aber wenn Du Dir den Code 
in 3 Jahren mal wieder ansiehst...

Außerdem sind die Werte in einem Array schneller da (Rechenzeit) und 
lassen sich, eine vernünftige Dokumentation vorausgesetzt, schneller 
ändern.

von wendelsberg (Gast)


Lesenswert?

Amateur schrieb:
> und
> lassen sich, eine vernünftige Dokumentation vorausgesetzt, schneller
> ändern.

spricht meines Erachtens genau dafuer!

wendelsberg

von Michael M. (mj09)


Lesenswert?

Hallo Zusammen,
danke für die Antworten.

Ich habe mich für die Lösung von lulu entschieden.
Ich finde diese Lösung am elegantesten.
Mit der nötigen Dokumentation ist der Weg für mich auch noch später 
nachvollziehbar.


Viele Grüße

Michael

von Hans (Gast)


Lesenswert?

Am klarsten finde ich immer noch die vier ifs. Kann man ja recht kompakt 
schreiben:
1
out = 0;
2
if (in & 1) out |= 0x03;
3
if (in & 2) out |= 0x0C;
4
if (in & 4) out |= 0x30;
5
if (in & 8) out |= 0xC0;

Oder:
1
out = 0;
2
out |= (in & 1) ? 0x03 : 0;
3
out |= (in & 2) ? 0x0C : 0;
4
out |= (in & 4) ? 0x30 : 0;
5
out |= (in & 8) ? 0xC0 : 0;

Oder wenn man es mehr als Zuordnungstabelle erkennen soll:
1
out = 0;
2
out |= (!!(in & 1) << 0);
3
out |= (!!(in & 1) << 1);
4
out |= (!!(in & 2) << 2);
5
out |= (!!(in & 2) << 3);
6
out |= (!!(in & 4) << 4);
7
out |= (!!(in & 4) << 5);
8
out |= (!!(in & 8) << 6);
9
out |= (!!(in & 8) << 7);

von Hans (Gast)


Lesenswert?

Oder etwas weniger intuitiv, aber auch hübsch:
1
out = 0;
2
out |= ((in & 1) << 0) | ((in & 1) << 1);
3
out |= ((in & 2) << 1) | ((in & 2) << 2);
4
out |= ((in & 4) << 2) | ((in & 4) << 3);
5
out |= ((in & 8) << 3) | ((in & 8) << 4);
Gibt unbegrenzt viele Möglichkeiten ... :-)

von Hans (Gast)


Lesenswert?

So, jetzt aber ... die Klammern kann man ja weglassen :-)
1
out = 0;
2
out |= !!(in & 1) << 0;
3
out |= !!(in & 1) << 1;
4
out |= !!(in & 2) << 2;
5
out |= !!(in & 2) << 3;
6
out |= !!(in & 4) << 4;
7
out |= !!(in & 4) << 5;
8
out |= !!(in & 8) << 6;
9
out |= !!(in & 8) << 7;

Oder so?
1
out = 0;
2
//                  in    out
3
out |= !!(in & (1 << 0)) << 0;
4
out |= !!(in & (1 << 0)) << 1;
5
out |= !!(in & (1 << 1)) << 2;
6
out |= !!(in & (1 << 1)) << 3;
7
out |= !!(in & (1 << 2)) << 4;
8
out |= !!(in & (1 << 2)) << 5;
9
out |= !!(in & (1 << 3)) << 6;
10
out |= !!(in & (1 << 3)) << 7;

von Hans (Gast)


Lesenswert?

Oder stehst Du vielleicht auf Makros? :-D
1
#define MAP_OUT_IN(bit_out, bit_in) out |= !!(in & (bit_in)) << (bit_out)
2
out = 0;
3
MAP_OUT_IN(0, 0);
4
MAP_OUT_IN(1, 0);
5
MAP_OUT_IN(2, 1);
6
MAP_OUT_IN(3, 1);
7
MAP_OUT_IN(4, 2);
8
MAP_OUT_IN(5, 2);
9
MAP_OUT_IN(6, 3);
10
MAP_OUT_IN(7, 3);

von Bastler (Gast)


Lesenswert?

Dirk B. schrieb:
> Bastler schrieb:
>> Array aus 16 Byte-Werten?
>
> Ohne Fragezeichen!

Mit!
Bewährtes Verfahren. Wer was lernen will, braucht nicht die Lösung, 
sondern die Richtung in die er/sie weitergehen soll. Dazu benutze ich 
gern eine (provozierende) FRAGE.

von Peter D. (peda)


Lesenswert?

1
out = in & 1;
2
out += (in & 2) << 1;
3
out += (in & 4) << 2;
4
out += (in & 8) << 3;
5
out += out << 1;

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

auf dem AVR wäre auch noch ein Einzeiler möglich:
1
out = __builtin_avr_insert_bits (0x33221100, in, 0);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.