Frage Bitoperation

Gast #5203084
Lesenswert?

Hallo liebe Leute,

habe eine Frage, wo ich nicht so recht weiterkomme. Es sind zwei uint8_t 
Variablen vorhanden, nennen wir var_new und var_old. Nun will ich ein 
bestimmtes Bit (sagen wir Bit 0) von var_new nach var_old kopieren.

Aktueller Versuch sieht so aus:
1
var_old |= var_new&(1<<0);

Nur ist die Operation allerdings falsch, da es schlichtweg nicht 
funktioniert. Ich behelfe mir aktuell mit einer einfache if-Abfrage
1
if (var_new&(1<<0))
2
   { var_old |= (1<<0);}
3
else 
4
   { var_old &= ~(1<<0);}

Aber das muss doch irgendwie in einem Schritt gehen! Wahrscheinlich sehe 
ich den Wald vor lauter Bäume nicht...
Gast #5203118
Lesenswert?

Noob schrieb:

> Aber das muss doch irgendwie in einem Schritt gehen!

Nein. Auch wenn du einen komplexen Ausdruck in C in einer Zeile 
schreiben kannst, werden es dadurch nicht weniger "Schritte". Die 
if-Konstruktion ist schon garnicht schlecht, der Compiler kann die recht 
gut optimieren.

Wenn du die unbedingt in eine Zeile quetschen willst, wazu auch immer 
das gut sein soll, kannst du sie ja auch so schreiben:

(var_new&(1<<0))? var_old |= (1<<0): var_old &= ~(1<<0);

Auf'm AVR8 kommt dann vermutlich sowas raus:

sbrc reg_new,0
ori reg_old,1
sbrs reg_new,0
andi reg_old,~1

was mit vier Takten schon nicht schlecht ist. Vielleicht schafft der 
Compiler aber sogar das Optimimum

bst reg_new,0
bld reg_old,0

Aber auch das sind immer noch ZWEI Schritte, also zwei Takte. In einem 
Schritt ist das Problem schlicht nicht lösbar. Jedenfalls nicht auf 
einem AVR8.

Bei den anderen Vorschlägen im Thread wird mit einiger 
Wahrscheinlichkeit etwas herauskommen, was weniger effizienten Code 
erzeugt. Irgendwas in der Art:

andi reg_old,~1
andi reg_new,1
or reg_old,reg_new

Merke: Was du in C hinschreibst, interessiert den Gasmann. Wichtig ist 
letztlich, was der Compiler draus macht. Auf C-Ebene sollte es vor allem 
eins sein: gut lesbar. Und dafür ist es NICHT hilfreich, soviel wie 
möglich in eine Zeile zu quetschen. Und davon wird der erzeugte Code 
typischerweise auch weder schneller noch kleiner. Also: kompletter 
Unsinn, hier zu "optimieren".
Gast #5203527
Lesenswert?

> Aber das muss doch irgendwie in einem Schritt gehen!

Da haben wohl die Konstrukteure des ENIAC eine falsche Entscheidung 
getroffen. Und danach hat 80 Jahre lang kein Prozessorentwickler mehr 
darüber nachgedacht.
Moderator (Firma: Titel) Persönliche Seite #5203571
Lesenswert?

c-hater schrieb:
> Wenn du die unbedingt in eine Zeile quetschen willst, wazu auch immer
> das gut sein soll, kannst du sie ja auch so schreiben:
Da fehlen noch Klammern:
http://codepad.org/t3NSZth8

Noob schrieb:
> Aktueller Versuch sieht so aus:
> var_old |= var_new&(1<<0);
> Nur ist die Operation allerdings falsch, da es schlichtweg nicht
> funktioniert.
Oh doch, aber funktioniert nur zur Hälfte.
Also nur, wenn ein Bit zu setzen ist. Denn nur das kann das '|' 
bewirken.

Du müsstest also noch eine zweite Zeile hinzufügen, die das Bit vorher 
löscht:
1
    var_old &= ~(1<<0);         // erst löschen
2
    var_old |= var_new&(1<<0);  // ggfs wieder setzen
http://codepad.org/Y8hbvebb

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren