Hallo, ich brauche folgende "Umrechnung": 0 -> 0 1-8 -> 8 9-16 -> 16 17-24 -> 24 25-32 -> 32 Wie würdet ihr das am effektivsten in C implementieren? Gruß Reinhold
Eine einfache if-else-Konstruktion ist sicher nicht ineffektiv. Wenn der Compiler einigermaßen gut ist, sind das wenige Takte und relativ wenig Code. Etwas Effektiveres fällt mir spontan nicht ein. Da die 'Bereichsgrenzen' Vielfache von acht sind, könnte man vielleicht nochwas über das dritte Bit machen, aber selbst wenn das geht, wird das nicht viel kürzer und schneller werden als mit if.
Reinhold schrieb: > ich brauche folgende "Umrechnung": > > 0 -> 0 > 1-8 -> 8 > 9-16 -> 16 > 17-24 -> 24 > 25-32 -> 32 > > Wie würdet ihr das am effektivsten in C implementieren?
1 | ((x + 7) / 8) * 8; |
Viele Grüße, Simon
mit dem vielfachen von 8 kann man wirklich was machen: die zahl in 2 teile splitten: 1. Teil: bit(0,1,2) 2. Teil: bit(3,4,5,6,...) und dann nur noch ausgabe: return (2.teil+1.teil!=0)+"000" die letzten 3 stellen sind 0 wegen runden und der vordere teil ggf. +1 wenn wir kein vielfaches von 8 haben
Ich würde den Compiler gar nicht erst "auf dumme Gedanken bringen", eine Division und einen Multiplikation zu verwenden. ;-) Dem kürzestmöglichen Maschinencode dürfte folgendes C-Konstrukt nahekommen: int In, Out; Out = ((In+7)<<3)>>3;
Simon Budig schrieb: > ((x + 7) / 8) * 8; float oder int? float: return x+7; int: x+7 und dann die letzten 3 bits auf 000 setzten
Abakus schrieb: > Ich würde den Compiler gar nicht erst "auf dumme Gedanken bringen", eine > Division und einen Multiplikation zu verwenden. ;-) > > Dem kürzestmöglichen Maschinencode dürfte folgendes C-Konstrukt > nahekommen: > > int In, Out; > > Out = ((In+7)<<3)>>3; Und wuppdich haben wir den Beweis, warum es manchmal doch besser ist, die Division/Multiplikation einfach hinzuschreiben... :-) Viele Grüße, Simon
Abakus schrieb: > Dem kürzestmöglichen Maschinencode dürfte folgendes C-Konstrukt > nahekommen: > > int In, Out; > > Out = ((In+7)<<3)>>3; enthält leider gleich mehrere mögliche Problemfälle: 1. Falls In > 8185 (0x1FF9) oder < -8192 (0xE000) ist ergibt sich ein Überlauf und damit eine ungewollte Änderung der Bits. 2. in Ansi-C ist rechts-schieben von negativen Zahlen (Datentyp int) undefiniert. Wenn ich also (-1) >> 1 schreibe erhalte ich je nach Compiler als Ergebnis entweder -1 (rechts shift mit Vorzeichenerweiterung) oder 32767 (rechts shift ohne Vorzeichenerweiterung). ich würde schreiben: Y = (X+7) & 0xFFF8; Die Und-Maske ist natürlich an den Datentyp anzupassen. Ich gehe mal von uint16_t aus. Der TE muß dann nur noch überlegen was mit Überläufen für X >= 65529 (>= 0xFFF9) passieren soll. Gruß Anja
Hallo zusammen, vielen Dank für die Inspirationen! Ich habe nun diese Variante benutzt: y = (x + 7) & 0xF8; Ich benutze als Datentyp uint8_t (hatte ich vergessen zu erwähnen). Der Spezialfall für Werte > 248 ist unkritisch, so groß wird der Wert nie. Liebe Grüße Reinhold
Reinhold schrieb: > Wie würdet ihr das am effektivsten in C implementieren? Reinhold schrieb: > y = (x + 7) & 0xF8; Beim GCC-Compiler und uint8_t kann es sinnvoll sein für den Zwischenwert (x + 7) eine Registervariable vom Typ uint8_t zu spendieren um den compiler zu überreden alles als uint8_t zu rechnen (und nicht als uint16_t). also so: register uint8_t z; z = x + 7; y = z & 0xF8;
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.