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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.