Die einzige "1" in einem Byte (uint8_t) kann ich sehr einfach nach links (<<) und nach rechts (>>) verschieben: 00000010 00010000 (<<3) 00000100 (>>2) Es werden zwar alle Bits verschoben, sichtbar wandert aber nur die "1". Nun soll aber die einzige "0" verschoben werden: 11110111 11101111 11011111 10111111 01111111 10111111 11011111 Ist nicht mehr so einfach?
Doch ist genauso einfach. Du meinst vermutlich die Werte der Bits, die hineingeschoben werden. Da fallen mir 4 Taktiken ein : a) schiebe den Wert 0 hinein b) schiebe den Wert 1 hinein c) schiebe den Wert der am anderen Ende herauspurzelt hinein d) schiebe den Wert des Carry-Flags hinein und lade das Carry-Flag mit dem Wert, der am anderen Ende herausfällt Wobei C an und für sich erstmal nur a) beherrscht. Aber mit ein wenig Bit hin und her gewurschtel kommt man auf b) oder c)
1 | a) x <<= 3; |
2 | b) x = (x << 3) | 7; |
3 | c) x = (x << 3) | (x >> 5); |
Georg M. schrieb: > Es werden zwar alle Bits verschoben, sichtbar wandert aber nur die "1". > Nun soll aber die einzige "0" verschoben werden Das, was du da willst, nennt sich im Grunde "rotieren": das was links oder rechts rausfällt, soll auf der jeweils anderen Seite wieder hineingeschoben werden. Der Assembler kann das ganz einfach, da gibt es entsprechende Rotationsbefehle ror und rol. In C ist das wie schon dargestellt aufwändiger und leider kapiert mit annehmbarer Wahrscheinlichkeit der Compiler nicht, dass er ror und rol verwenden könnte: https://www.google.com/search?q=rotate+in+c
:
Bearbeitet durch Moderator
zyxwv schrieb: > Du meinst vermutlich Bei den Beispielen oben wird nicht von Konstanten ausgegangen. Oder anders: was ergibt "11011111 ror 2"? Was ergibt "11110111 ror 2"? Georg M. schrieb: > Ist nicht mehr so einfach? Manchmal wäre es echt nicht schlecht, das eigentliche Problem zu kennen und nicht nur den geplanten Lösungsansatz dafür...
Nach rechts geht es "einfach", wenn die 0 nicht an Bit 7 (ganz links) steht und int8_t statt uint8_t verwendet wird. Wenn es aber nur eine 0 enthält, reicht auch eine Tabelle von 8 einträgen, über die man itteriert (mit %8)
A. S. schrieb: > Wenn es aber nur eine 0 enthält, reicht auch eine Tabelle von 8 > einträgen, über die man itteriert (mit %8) Ja, aber in dieser Tabell muss man erst mal den aktuellen Wert finden, wenn dieses Bitmuster von aussen kommt. Und wenn das Bitmuster es quasi als "Index" im eigenen Programm verwaltet wird (z.B. Spalte/Zeile eines LED-Multiplexers), dann wäre es sinnvoller, den Index abzuspeichern und daraus jeweils das Bitmuster zu berechnen. Wie gesagt: was ist das Problem, das hier gelöst werden soll?
Lothar M. schrieb: > Manchmal wäre es echt nicht schlecht, das eigentliche Problem zu kennen Beim EEPROM gilt 0xFF als gelöscht, und da dachte ich: ok, dann mache ich auch meinen ganzen Code invers. Aber offensichtlich gibt es keine Gleichberechtigung/Gleichbehandlung bei den Nullen und Einsen.
Lothar M. schrieb: > In C ist das wie schon dargestellt > aufwändiger und leider kapiert mit annehmbarer Wahrscheinlichkeit der > Compiler nicht, dass er ror und rol verwenden könnte: Meeep. Das können so gut wie alle Compiler seit über einem Jahrzeht. Ist eine der einfachsten Optimierungsstufen. Und da es häufig in Hash funktionen vorkommt macht es auch praktisch Sinn: Beispiel: https://godbolt.org/z/qza33Ys55
1 | uint8_t f(uint8_t a) |
2 | { |
3 | return (a<<1) | (a >>7); |
4 | } |
1 | mov eax, edi |
2 | rol al |
3 | ret |
Georg M. schrieb: > Aber offensichtlich gibt es keine > Gleichberechtigung/Gleichbehandlung > bei den Nullen und Einsen. Natürlich nicht - vor allem wenn (E)EPROMs mitspielen wollen.
Nils schrieb: > Das können so gut wie alle Compiler seit über einem Jahrzeht. Ist ja nett, dann machen wir das künftig genau so... ;-) Georg M. schrieb: > Beim EEPROM gilt 0xFF als gelöscht, und da dachte ich: ok, dann mache > ich auch meinen ganzen Code invers. > Aber offensichtlich gibt es keine Gleichberechtigung/Gleichbehandlung > bei den Nullen und Einsen. Gleichberechtigung war im Grunde auch nie ein Ziel... ;-) Georg M. schrieb: > Beim EEPROM gilt 0xFF als gelöscht, und da dachte ich: ok, dann mache > ich auch meinen ganzen Code invers. Beim EEPROM ist es schnurz, weil du da das Schreiben vom Löschen meistens sowieso nicht entkoppeln kannst. Sprich: wenn schon irgendwas im EPROM steht und du willst eine 0x00 reinschreiben, dann wird die Speicherzelle erst auf 0xff gelöscht, und dann alle Bits auf 0 geschrieben. Du gewinnst im Grunde also nichts.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.