Hi Ich habe eine 64 Bit Binärzahl, in der steht leider das niederwertigste Bit links, das höchstwertige rechts. Bevor ich jetzt anfange, jedes Bit einzeln umzusortieren, frage ich erstmal: Gibt es eine einfache (mathematische) Möglichkeit, die ganze Zahl um 180° zu drehen?
:
Verschoben durch Moderator
In Assembler würde ich es aus einem Register z.B. links herausschieben und über das Carryflag in ein anderes Register links reinschieben. Für 64 Bit sind das allerdings 16 Register, in einem 8-Bitter wie dem AVR ist damit schon die Hälfte aller Register belegt.
:
Bearbeitet durch User
Hier werden mehrere Möglichkeiten vorgestellt: http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
Ingo L. schrieb: > for ( uint8_t i = 0; i<64; i++ ){
1 | for ( uint8_t i = 0; i<=64; i++ ){ |
selber reingefallen :(
:
Bearbeitet durch User
Beitrag #7415276 wurde vom Autor gelöscht.
1 | uint64_t Flip ( uint64_t Zahl ) |
2 | {
|
3 | uint64_t Temp = 0; |
4 | for ( uint8_t i = 0; i<=64; i++ ){ |
5 | if ( Zahl & (1ul<<(64-i)) ) // Von links anfangen |
6 | Temp |= (1ul<<i); // und rechts einsortieren |
7 | }
|
8 | return Temp; |
9 | }
|
Das kann man noch weiter optimieren, aber verständlicher Code ist gut wartbar
:
Bearbeitet durch User
Ingo L. schrieb: >
1 | for ( uint8_t i = 0; i<=64; i++ ) |
Off by one error! So vielleicht?
1 | uint64_t flip_again(uint64_t in) { |
2 | uint64_t out = 0; |
3 | for (uint8_t i = 0; i < 64; i++, in >>= 1) |
4 | out = in & 1 ? (out << 1) | 1 : out << 1; |
5 | return out; |
6 | }
|
:
Bearbeitet durch User
Norbert schrieb: > So vielleicht? Geht auch, aber schlecht lesbar und schlecht wartbar. Norbert schrieb: > for ( uint8_t i = 0; i<=64; i++ ) > > Off by one error! Ja, leider verrissen :(, Informatiker 0-Problem Hier nochmal in lesbar
1 | uint64_t Flip ( uint64_t Zahl ) |
2 | {
|
3 | uint64_t Temp = 0; |
4 | for ( uint8_t i = 0; i<64; i++ ){ // Schleife läuft von 0...63 |
5 | if ( Zahl & (1ul<<(63-i)) ) // Von links anfangen |
6 | Temp |= (1ul<<i); // und rechts einsortieren |
7 | }
|
8 | return Temp; |
9 | }
|
:
Bearbeitet durch User
Peter N. schrieb: > Ich habe eine 64 Bit Binärzahl, in der steht leider das niederwertigste > Bit links, das höchstwertige rechts. Woher kommt die? Oder andersrum: kannst du die nicht gleich beim Einlesen richtig sortieren?
:
Bearbeitet durch Moderator
> Gibt es eine einfache (mathematische) Möglichkeit, die ganze Zahl um > 180° zu drehen? Klar einfach auf dem karierten Mathepapier die Zahlen in umgekehrter Schreibweise (reverse order) hinschreiben .... Ohne zu wissen, welche Möglichkeiten/Tools du hast/kennst/dich_nicht_zierst_zu_benutzen kann man die Frage nicht beantworten! Manche Prozessoren haben einen Maschienenbefehl um die Reihenfolge zu tauschen (DSP, Cortex -> RBIT). Siehe Anhang. Dann kann man sich mit Schiebe/Rotationsbefehlen was basteln, vielleicht kann man mit einem Barrel-shifter was beschleunigen Für PLD schreibt am einfach die Zeile sig_a(31 downto 0) <= sig_b(0 to 31) und die tools basteln die Umverdrahtung. Ein Blick in die maschinennahen Bibliotheken (bspw.: CMSIS) kann auch nicht schaden. Also hilf dir selbst, dann hilft dir Gott!
Christoph db1uq K. schrieb: > Für 64 Bit sind das allerdings 16 Register, in einem 8-Bitter wie dem > AVR ist damit schon die Hälfte aller Register belegt. Man muss ja nicht alles um 64 Bit schieben. Je nach Architektur und Sprache Byte oder Wordweise und dann umsortieren.
Moin, Einfach mit einer Lookup-Table arbeiten. Passt genau in 131072 PiByte ;-) Gruss WK
Ingo L. schrieb: > J. R. schrieb: >> Je nach Architektur > Die ja streng geheim ist... Aber mit Architektur kennt sich der TO aus, er weiß was 180° im Bauwesen bedeutet ... "... die ganze Zahl um 180° zu drehen ..." Echt, wo die Grundlage fehlt, ist Hopfen, Malz und guter Rat verschwendet.
Ingo L. schrieb: >> Je nach Architektur > Die ja streng geheim ist... Es geht wohl um PicoMite (BASIC) und den RP2040 ;-) Beitrag "allgemeine PicoMite Anfängerfragen"
Mi N. schrieb: > Ingo L. schrieb: >>> Je nach Architektur >> Die ja streng geheim ist... > > Es geht wohl um PicoMite (BASIC) und den RP2040 Na dann ist es doch einfach, weil "MMBasic allows the embedding of compiled C programs for high performance functions" Also einfach den vorgeschlagenen ARM-maschinenbefehl ("RBIT") als online in C einbinden, kompilieren und dem Basic vor die Füße werfen. Ferdsch! Beitrag "Re: Zahl umdrehen?" Wobei, der RP2040 als CortexMo doch 32bit lange Register hat?!
Interessanterweise gibt es im GCC zwar Builtins um Bytes, Halbworte etc umzudrehen, nicht aber bei Bits. Genau das wäre aber die sinnvollste Stelle, weil viele Architekturen entsprechenden Hardware-Support haben.
straight code wenn der Prozessor Byte-Orientiert ist (ungetestet):
1 | typedef unsigned char BYTE; |
2 | |
3 | BYTE revBYTE(BYTE b) |
4 | {
|
5 | /*z.B. so. Der Compiler weiss, was er daraus macht */
|
6 | b = (b & 0xf0)>>4 | (b & 0x0f)<<4; |
7 | b = (b & 0xcc)>>2 | (b & 0x33)<<2; |
8 | b = (b & 0xaa)>>1 | (b & 0x55)<<1; |
9 | }
|
10 | |
11 | void foo(void) |
12 | {
|
13 | BYTE *pIn = (BYTE*) &DeineZahlIn; |
14 | BYTE *pOut = (BYTE*) &DeineZahlOut + sizeof(DeineZahlIn); |
15 | BYTE *pInEnd= pIn + sizeof(DeineZahlIn); |
16 | |
17 | do {*--pOut = revBYTE(*pIn++);} while(pIn < pEnd); |
18 | }
|
:
Bearbeitet durch User
Peter N. schrieb: > Gibt es eine einfache (mathematische) Möglichkeit, die ganze Zahl um > 180° zu drehen? mathematisch nicht, aber gewusst wie. "Mathematisch" könnte man sich an Haskell versuchen. https://stackoverflow.com/questions/19725292/how-to-reverse-an-integer-in-haskell Der grobe Ansatz da ist aber u.a. die "Zahl" in eine Liste zu verwandeln, und diese dann umdrehen - was sich leichter automatisieren wie auch gezielter angehen lässt. Ja nach Hardware hat man noch andere Möglichkeiten, Goodies hier, Goodies da - nur dann muss man die Hardware kennen. Kenn man die Hardware nicht, könnte man sich zumindest mal den den Asm-Code vom (c-)Compiler (s.o.) genauer ansehen. Um Verwirrungsalarm aus dem Weg zu gehen, sollte man sich mehrere Lösungsansätze ansehen, u.a. auch https://www.techiedelight.com/de/inplace-rotate-matrix-180-degrees/
DSGV-Violator schrieb: > Also einfach den vorgeschlagenen ARM-maschinenbefehl ("RBIT") als online > in C einbinden, kompilieren und dem Basic vor die Füße werfen. Ich befürchte allerdings das der CortexM0+ ein »RBIT« leider gar nicht in seinem Repertoire hat… Allerdings verfügt er über PIOs samt Assembler, da könnte man mal hinein schauen. Aber vorher anschnallen, …
Ingo L. schrieb: > Geht auch, aber schlecht lesbar… Na ja, wir reden hier von stattlichen zwei Zeilen mit Gehalt. Da muss man die beiden halt öfter lesen… > …und schlecht wartbar. Na ja, wir reden hier von stattlichen zwei Zeilen mit Gehalt. Da muss man die beiden halt mal verstehen…
Rbx schrieb: > Ja nach Hardware hat man noch andere Möglichkeiten, Goodies hier, > Goodies da - nur dann muss man die Hardware kennen Mit 16 GPIO kannst Du das einzelne Byte per HW spiegeln. Mit 128 GPIO auch den ganzen Wert.
Dergute W. schrieb: > Einfach mit einer Lookup-Table arbeiten. Passt genau in 131072 PiByte Wenn man eine Lookup-Tabelle für 8 Bit-Zahlen erstellt, belegt diese ganze 256 Bytes. Soviel Platz im ROM sollte sein. Dann kann man die 64bit-Zahl in 8 Schritten à 1 Byte umdrehen. Das ginge deutlich schneller als die 64Bits einzeln zu schieben.
Moin, Fritz G. schrieb: > Dergute W. schrieb: >> Einfach mit einer Lookup-Table arbeiten. Passt genau in 131072 PiByte > Wenn man eine Lookup-Tabelle für 8 Bit-Zahlen erstellt, belegt diese > ganze 256 Bytes. Soviel Platz im ROM sollte sein. Dann kann man die > 64bit-Zahl in 8 Schritten à 1 Byte umdrehen. Das ginge deutlich > schneller als die 64Bits einzeln zu schieben. Ja, wenns ums Platzsparen geht, dann wird man mit einer 1bit LUT noch viel mehr sparen koennen... scnr, WK
Ich würde es mit einer Mischlösung von Tabellenumrechnung und Bytevertausch versuchen:
1 | #include <stdio.h> |
2 | #include <stdint.h> |
3 | |
4 | static const uint8_t bitReverseTable[256] = { |
5 | 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, |
6 | 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, |
7 | 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, |
8 | 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, |
9 | 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, |
10 | 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, |
11 | 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, |
12 | 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, |
13 | 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, |
14 | 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, |
15 | 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, |
16 | 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, |
17 | 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, |
18 | 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, |
19 | 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, |
20 | 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, |
21 | 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, |
22 | 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, |
23 | 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, |
24 | 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, |
25 | 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, |
26 | 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, |
27 | 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, |
28 | 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, |
29 | 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, |
30 | 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, |
31 | 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, |
32 | 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, |
33 | 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, |
34 | 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, |
35 | 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, |
36 | 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF |
37 | };
|
38 | |
39 | uint64_t reverse64(uint64_t num) { |
40 | |
41 | union RN { |
42 | uint64_t val64; |
43 | uint8_t val8[8]; |
44 | }
|
45 | |
46 | RN rn_i,rn_o; |
47 | |
48 | rn_i.val64 = num; |
49 | |
50 | rn_o.val8[0] = bitReverseTable[rn_i.val8[7]]; |
51 | rn_o.val8[1] = bitReverseTable[rn_i.val8[6]]; |
52 | rn_o.val8[2] = bitReverseTable[rn_i.val8[5]]; |
53 | rn_o.val8[3] = bitReverseTable[rn_i.val8[4]]; |
54 | rn_o.val8[4] = bitReverseTable[rn_i.val8[3]]; |
55 | rn_o.val8[5] = bitReverseTable[rn_i.val8[2]]; |
56 | rn_o.val8[6] = bitReverseTable[rn_i.val8[1]]; |
57 | rn_o.val8[7] = bitReverseTable[rn_i.val8[0]]; |
58 | |
59 | return rn_o.val64; |
60 | }
|
**ACHTUNG**: Bit- und Byteorder kann von der Prozessorplattform abhängig sein!
:
Bearbeitet durch User
Gerald K. schrieb: > **ACHTUNG**: Bit- und Byteorder kann von der Prozessorplattform abhängig > sein! Und welchen Einfluss könnte das auf Deinen Code haben?
Bruno V. schrieb: > Und welchen Einfluss könnte das auf Deinen Code haben? Gute Frage. Das wirkt sich natürlich auf die Bytetauscherei aus. Dann muss z.B. nicht [0] mit [7], sondern [7] mit [0] getauscht werden. 😀
Norbert schrieb: > Allerdings verfügt er über PIOs samt Assembler, da könnte man mal hinein > schauen. Aber vorher anschnallen, … Ach watt, völlig trivial. Das ist ein Fünfzeiler, davon nur drei Instruktionen. pull block, mov ISR, OSR (mit Operation "bit-reverse"), push noblock. Sprich: wenn die PIO mit Systemtakt läuft, braucht das Teil drei CPU-Takte für die Operation.
C-hater schrieb: > Norbert schrieb: > >> Allerdings verfügt er über PIOs samt Assembler, da könnte man mal hinein >> schauen. Aber vorher anschnallen, … > > Ach watt, völlig trivial. Das ist ein Fünfzeiler, davon nur drei > Instruktionen. pull block, mov ISR, OSR (mit Operation "bit-reverse"), > push noblock. > > Sprich: wenn die PIO mit Systemtakt läuft, braucht das Teil drei > CPU-Takte für die Operation. Mist, übersehen: es ging um eine 64Bit-Zahl. Dann wird's doch etwas länglicher, dann sind's sieben Operationen (also sieben Takte): pull block mov X, Bit-Revers OSR pull block mov ISR, Bit-Revers OSR push noblock mov ISR, X push noblock
Beitrag #7415903 wurde von einem Moderator gelöscht.
Beitrag #7415906 wurde von einem Moderator gelöscht.
C-hater schrieb: > Ach watt, völlig trivial. Stimmt. Diesen Vorschlag hatte ich nämlich schon vor einigen Tagen auf Github in MicroPython Discussions gepostet…
Peter N. schrieb: > Bevor ich jetzt anfange, jedes Bit einzeln umzusortieren, frage ich > erstmal: Naja. Die Frage ist schlicht, wie schnell es denn WIRKLICH sein muss? Du musst sicher NICHT die Zahl in 1us umdrehen und auch nicht 1M davon. Wenn der triviale Ansatz der Bitschieberei schnell genug ist, nimm ihn und wende dich den wirklich wichtigen und interessanten Aufgaben deines Projektes zu. https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung Gilt sehr allgemein für viele Dinge, nicht nur in der Elektronik und Software.
Norbert schrieb: > C-hater schrieb: >> Ach watt, völlig trivial. > > Stimmt. Diesen Vorschlag hatte ich nämlich schon vor einigen Tagen auf > Github in MicroPython Discussions gepostet… Welchen? 32Bit oder 64Bit? Und wo finde ich auf github irgendwelche Diskussionsforen?
C-hater schrieb: > Welchen? 32Bit oder 64Bit? Und wo finde ich auf github irgendwelche > Diskussionsforen? github: MicroPython: Discussions Hab' erst eine recht schnelle Python-Viper Routine geschrieben, danach eine Python-Thumb-Assembler Version und dann den schnellsten Vorschlag mit PIO Assembler und DMA gemacht. Der war - wie du schon geschrieben hattest - so trivial, das ihn nur erwähnt hatte. War zwar nur 32bit, aber sinngemäß geht's natürlich mit beliebigen Bitweiten.
Norbert schrieb: > War zwar nur 32bit, aber sinngemäß geht's natürlich mit beliebigen > Bitweiten. Ähem, nö. Mit den einfachen PIO-Programmen ist bei diesem konkreten Problem bei 96 Bit Schicht im Schacht. Liegt daran, dass die PIO halt nur vier Register hat, davon nur zwei "frei verwendbare" (hier natürlich als Cache für das Reverse der Long-Words). 128Bit oder gar 256Bit mit vMax zu reversen braucht eine Kombination aus PIO und ARM-Assembler. Das ist dann schon nicht mehr ganz so trivial...
Beitrag #7415947 wurde vom Autor gelöscht.
Bei max. 2048b: Eine PIO-SM hat jeweils vier ›WORD‹ FIFO kann also 8*32b = 256b ohne weiteres halten. Vier davon sofort verarbeiten und vier im FIFO halten. Acht SM können so 2048b entgegen nehmen. Die Daten müssen ja sowieso irgendwo stehen, bevorzugt in einem array. Man kann 64 ›WORD‹ aus dem array lesen und ungebremst in die PIO-FIFOs schieben. Dann liest man ungebremst 64 ›WORD‹ und schreibt sie rückwärts in das array zurück. Wenn größer 2048b, dann kann man auch noch den Stapel nutzen. Wenn der nicht reicht, wird's akademisch… ;-)
Norbert schrieb: > Eine PIO-SM hat jeweils vier ›WORD‹ FIFO kann also 8*32b = 256b ohne > weiteres halten. Vier davon sofort verarbeiten und vier im FIFO halten. Die FIFOs sind aber leider aus der PIO heraus nicht wahlfrei zugänglich. Deswegen heißen die Befehle für den Zugriff darauf auch PUSH/POP. Sprich: die "Drehung" der Daten auf der Ebene von 32Bit-Wörtern ist nur über Zwischenspeicherung in der PIO möglich. Deswegen ist deren Registerzahl hier der limitierende Faktor. > Die Daten müssen ja sowieso irgendwo stehen, bevorzugt in einem array. Die PIO kann eben nicht wahlfrei darauf zugreifen, sondern nur als FIFO. Also nix mit Array. > Acht SM können so 2048b entgegen nehmen. Ja klar, mit mehr PIO-Instanzen geht natürlich mehr als mit nur einer.
C-hater schrieb: > Die FIFOs sind aber leider aus der PIO heraus nicht wahlfrei zugänglich. Wenn du Zahlen größer ›WORD‹ (sagen wir mal 8*32bit) in einem Speicherbereich liegen hast, dann müssen die sowieso in 32bit Stücken in den FIFO geschoben werden. Geht nicht anders. Bei einem zu spiegelnden 256bit Wert kann man mit einem ›mov‹ index 0 und acht ›ldr‹ RAM[index] ›add‹ index 1 ›str‹ TX_FIFO Befehlssequenzen ohne zu warten in den (Eingangs-)FIFO schreiben. Die ersten vier Werte holt sich das PIO-Programm direkt ab, reversiert und schreibt sie in den (Ausgangs-)FIFO. Der ›stalled‹ dann, weil voll. Die letzen vier Werte stehen jetzt noch im (Eingangs-)FIFO. Alles ist randvoll. Jetzt müssen die Werte gelesen werden und zurück in's RAM. Also wieder: ›mov‹ index 0 Acht mal ›ldr‹ RX_FIFO ›add‹ index 1 ›str‹ RAM[index] Sobald ein Wert aus dem RX_FIFO gelesen wird, rutscht den nächste automatisch aus dem TX_FIFO, wird gespiegelt und in den RX_FIFO geschoben. Damit sind schließlich die acht ›WORD‹ sowohl gespiegelt als auch (im RAM) vertauscht. Da braucht man noch nicht mal X und Y, ISR und OSR reichen aus. Und nur einen einzigen PIO-Assembler Befehl.
:
Bearbeitet durch User
Dem aufmerksamen Beobachter wird nicht entgangen sein, das die ›add‹ und ›str‹ Befehle im zweiten Teil getauscht werden müssen. Verfluchtes copy'n'paste. ;-) Leider kann man bei der momentanen Boardsoftware Beiträge nicht sinnvoll ändern.
:
Bearbeitet durch User
Wir wissen ja leider die Architektur nicht, aber zum Bit Reversal wurde in Hackers Delight meiner Meinung nach alles gesagt: https://github.com/hcs0/Hackers-Delight/blob/master/reverse.c.txt
Max H. schrieb: > Wir wissen ja leider die Architektur nicht Stimmt auffallend. Der TO hat dazu rein garnix gesagt. Und sich im Verlauf des Threads auch nie wieder zu Wort gemeldet. Also offensichtlich: TROLL. Aber sowas von.
Max H. schrieb: > Wir wissen ja leider die Architektur nicht, Peter hatte bereits einige Male Fragen zu Picomite Basic gestellt. Es darf mit einiger Wahrscheinlichkeit angenommen werden, das ein Pi Pico mit RP2040 (also ARM Cortex-M0plus) zum Einsatz kommt.
C-hater schrieb: > Also offensichtlich: TROLL. Aber sowas von. Und vermutlich noch nicht mal das Handbuch der CPU gelesen. Naja, er dachte wohl, es gib irgendeinen mathematischen Trick. Tatsächlich beziehen sich 180 Grad eher auf eine Kreisvorstellung. Wenn man das auf eine Uhr anwendet, braucht man praktisch nur die 12 nach unten ziehen. Wenn man 64 Bit kreisförmig anordnet, kann man das auch machen - per Rotation. In diesem Fall in 32 Schritten. Da wäre dann aber nur der obere Teil mit dem unteren vertauscht. Möglicherweise nicht das gesuchte Ergebnis Ganz abgesehen davon, dass das nicht die schnellste Methode wäre (s.o.). Gestern hatte ich noch zwei Links gefunden, die nur die Grundlagen bearbeiten, und deswegen hatte ich mir die erspart. Aber nach den vielen guten Hinweisen oben ist mir das jetzt auch egal ;) https://www.youtube.com/watch?v=wXGZ7o9HNss https://www.geeksforgeeks.org/c-program-for-program-for-array-rotation-2/
:
Bearbeitet durch User
Ich hätte nie gedacht, daß so eine für mich einfache Frage, soviele Reaktionen hervorruft... Norbert schrieb: > Es > darf mit einiger Wahrscheinlichkeit angenommen werden, das ein Pi Pico > mit RP2040 (also ARM Cortex-M0plus) zum Einsatz kommt. Genau so ist es. Aber ich wollte allgemeine und einfache Antworten, die ich in PicoMite umsetzten kann, deshalb keine näheren Angaben. Mit den Kernen des RP2040 kann ich (noch lange) nichts anfangen... Ich habe das Problem auf die unelegante Weise gelöst: Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen zweiten String kopiert.
Peter N. schrieb: > Ich habe das Problem auf die unelegante Weise gelöst: > Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen > zweiten String kopiert. LOL. Ja geht so auch. Ist nur "ein wenig" suboptimal, was die Performance betrifft. Aber wenn's für dich langt: drauf geschissen.
Peter N. schrieb: > Ich habe das Problem auf die unelegante Weise gelöst: > Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen > zweiten String kopiert. Und warum dann nicht noch komplizierter? Du weisst doch, daß nix langsamer ist, als hantieren mit Strings? Und 64 Mal ein integer schieben ist immer noch um ein vielfacher schneller.
1 | #include <stdio.h> |
2 | #include <stdint.h> |
3 | |
4 | uint64_t DreheBitsUm(uint64_t zahl) { |
5 | uint64_t umgedreht = 0; |
6 | uint64_t nn = zahl; |
7 | for(;nn;nn >>= 1) { |
8 | umgedreht <<= 1; |
9 | umgedreht += (nn & 1); |
10 | }
|
11 | return umgedreht; |
12 | }
|
13 | |
14 | int main() { |
15 | uint64_t xx; |
16 | xx = DreheBitsUm(0xdeadbeef); |
17 | printf("Umgedreht = 0x%X", xx); |
18 | return 0; |
19 | }
|
Und dann vergleiche mal um wieviel schneller das ist...
:
Bearbeitet durch User
Marc V. schrieb: > for(;nn;nn >>= 1) { > > umgedreht <<= 1; > > umgedreht += (nn & 1); > > } Schnell aber falsch. Wenn man 0x1 rein schickt kommt kein 0x80000000 raus.
Mario M. schrieb: > Marc V. schrieb: >> for(;nn;nn >>= 1) { >> >> umgedreht <<= 1; >> >> umgedreht += (nn & 1); >> >> } > > Schnell aber falsch. Wenn man 0x1 rein schickt kommt kein 0x80000000 > raus. Lol.
1 | uint64_t DreheBitsUm(uint64_t zahl) { |
2 | //*********************************
|
3 | if (zahl == 1) return 0x80000000; |
4 | //*********************************
|
5 | uint64_t umgedreht = 0; |
6 | uint64_t nn = zahl; |
7 | for(;nn;nn >>= 1) { |
8 | umgedreht <<= 1; |
9 | umgedreht += (nn & 1); |
10 | }
|
11 | return umgedreht; |
12 | }
|
Zufrieden?
:
Bearbeitet durch User
Beitrag #7416530 wurde vom Autor gelöscht.
In der Form eines Sonntagsrätsels brauchbar. Wozu Algorithmus-Beschreibung oder sinnvolle Kommentare. Völlig überflüssig. Ist ja Freitag, das paßt. --- (Bezog sich auf den mittlerweile gelöschten Beitrag. Aber generell ist es auch meistens richtig)
:
Bearbeitet durch User
Beitrag #7416542 wurde vom Autor gelöscht.
Marc V. schrieb: > Peter N. schrieb: >> Ich habe das Problem auf die unelegante Weise gelöst: >> Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen >> zweiten String kopiert. > > Und warum dann nicht noch komplizierter? Daß es beim TO um PicoMite geht, sollte mittlerweile jedem klar sein. Dann gib ihm bitte auch ein Beispiel in BASIC, damit er etwas damit anfangen kann. Daß irgendetwas ganz schnell gehen müßte, war nicht die Frage. Nur steigert man sich hier gerne dahin, daß maximal ein CPU-Takt zulässig sei.
:
Bearbeitet durch User
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.