Gast
#1997306
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
|
Anzeige
|
Aufrundfunktion?
Gast
#1997306
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
Gast
#1997313
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?
Viele Grüße,
Simon
Gast
#1997320
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
Gast
#1997321
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;
Gast
#1997322
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
Gast
#1997374
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
Gast
#1998185
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
Gast
#1998391
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; Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|