www.mikrocontroller.net

Forum: Compiler & IDEs Binäre Zahl drehen


Autor: Dido (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe eine Frage und werde mich freuen, wenn mir jemand weiter
hilft. Wenn man eine binäre Zahl hat z.B 00101111 (8bit) wie kann man
am einfachsten in C die Rotieren damit man 11110100 am ende kriegt. Das
wäre für hilfreich, wenn man (wie mich) etwas inwertiert an einen Port
von einen AVR anhängt und schon fertiges Software hat und auch vile
ausgerechnete hex-Zahlen.

Danke für ihre hilfe!

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erstmal eine kurze nachfrage: willst du
das ganze um eine bestimmte anzahl rotieren?
invertieren (deinem beispiel nach nicht)?
oder oberes und unteres nibbel tauschen (scheint so)

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

für mich siehts eher nach ner Spiegelung der Bits aus. Also 7->0 6->1
usw.

Am schnellsten geht das mit einer Look-Up-Tabelle. Das kostet
allerdings 256 Byte Flash. Ansonsten hat hier im Forum mal jemand einen
passenden Code gepostet. Einfach mal nach Bit und spiegeln suchen.

Matthias

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Thema ist schon paarmal diskutiert worden.  Du findest es in den
Annalen dieses Forums.  Für 16-und-mehr-Bit-Zahlen gibt's einen
netten
C-Trick, für 8-Bit-Zahlen lohnt der eigentlich nicht, weil die
einfache Rotationsschleife (zumindest in inline asm) kürzer ist als
der coole Trick.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dafür gibt es die assemblerbefehle rol und ror.
die musst du dann 8x auf dein arbeitsregister anwendenund schon hast du
das von dir erwartete ergebniss.
einen schnelleren befehl oder lösung habe ich für dieses problem auch
noch nicht gefunden.

MfG
Sebastian

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine bitweise Spiegelung bekommt man mit ROL/ROR alleine nicht hin.

  76543210 -> ROR
= C7654321 (0 im Carry)

  C7654321 -> ROR
= 0C765432 (1 im Carry)

  0C765432 -> ROR
= 10C76543 (2 im Carry)

Gewollt ist aber:

  76543210 -> Operation X
  01234567

Für eine 4-Bit-Zahl sähe das in C so aus:

  Wert = ((Wert & 1) << 3) | (((Wert >> 1) & 1) << 2) | (((Wert >> 2) &
1) << 1) | ((Wert >> 3) & 1);

Das ist aber aufgrund der vielen Schiebeoperationen sehr ineffizient
in Assemblercode umzusetzen, erst recht, wenn man das auf 8 Bit
ausweitet.

Autor: Sebastian Schildt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>

static _inline_ uint8_t
mirror(uint8_t b)
{
        uint8_t res;

        _asm_ volatile("ldi r25, 8" "\n"
                        "1: ror %1" "\n"
                        "rol %0" "\n"
                        "dec r25" "\n"
                        "brne 1b":
                        "=&r" (res):
                        "r" (b):
                        "r25");
        return res;
}

int
main(void)
{
        uint8_t i;

        i = 0x6f;
        i = mirror(i);

        return i;
}

Autor: Dido (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich danke euch alle fuer die super schnellen Antworten! Leider hatte ich
erst jetzt Zeit die zu lesen. Also es ist  nicht trivial so was zu
machen. Habe gehofft auf eine Loesung mit 2-3 assembler befehlen, aber
leider nicht der Fall. Dann werde ich am besten alle Hex zahlen einfach
mit den vorgeschlagenen C beispiele neu umrechnen um uebefluessiges Code
zu sparen.

Gruesse Dido

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

mit einer Look-UP Tabelle ist es trivial. Aber es kostet halt ein
bischen Speicher. Auf einem Mega128 ist das kein Problem. Auf einem
2313 evtl. aber schon.

Matthias

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einige Prozessoren haben Befehle*, um zwei Nibbles zu vertauschen. Damit
kann man die Größe der Lookup-Table deutlich (auf 16 Bytes) reduzieren.

Also:

7654 3210

Lookuptable auf untere vier Bit anwenden

7654 0123

Nibbles tauschen

0123 7654

Lookup-Table auf untere vier Bit anwenden

0123 4567

Das sollte sich realisieren lassen.

*) MCS51 & AVR: SWAP

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz davon abgesehen, die von mir vorgeschlagene Lösung beinhaltet
doch nur zwei Assemblerbefehle für die eigentliche Bitschieberei, drei
weitere werden für die Schleife gebraucht.  OK, es sind paar Takte
mehr als mit der lookup table, genauer: 8 * 5 + 1 Takte.  Wie schnell
musst Du denn sein?

Die von Rufus vorgeschlagene Variante hat natürlich auch was, ist
dafür ein wenig aufwendiger zu codieren.  Mit bisschen Glück kann man
die sogar komplett in C schreiben, irgendwie kann ich mich erinnern,
dass der AVR-GCC den SWAP-Befehl auch hineinoptimieren kann.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.