Hallo, wie kann man am Besten 2 8Bit Variablen in eine 16Bit Variable kopieren? Durch Schiebeoperationen? Das muss doch auch effizienter gehen? Gruß Bernd
neumann schrieb: > Das muss doch auch effizienter gehen? Effizienter als Schieben und oder Verknüpfung/Zuweisung? Wohl kaum!
Wenn Du mehr tust, als die Behauptung
>Das muss doch auch effizienter gehen...
in den Raum zu stellen, könnte man ja mal darüber nachdenken.
Ansonsten würde ich Dir das umgekehrte Verfahren empfehlen.
Implementiere es, schau Dir den Assemblercode an
und denk nochmal d'rüber nach.
Ja, das geht definitiv effizienter: Variablen im Speicher hintereinander ablegen ;)
#include <stdint.h> ... uint8_t var1 = 0x12; uint8_t var2 = 0x34; uint16_t var3 = (var1 << 8) | var2;
>uint16_t var3 = (var1 << 8) | var2;
Ich vermute mal, das hier nur der Wert von var2 in var3 stehen wird.
Was erwartest du denn für ein Verhalten, wenn du zwei VORZEICHENBEHAFTETE 8-Bit Werte in einen 16bit Wert verwandelst?
Matthias Lipinsky schrieb: >>uint16_t var3 = (var1 << 8) | var2; > > Ich vermute mal, das hier nur der Wert von var2 in var3 stehen wird. Nein. (Integer-Promotion!)
Floh schrieb: > Was erwartest du denn für ein Verhalten, wenn du zwei > VORZEICHENBEHAFTETE 8-Bit Werte in einen 16bit Wert verwandelst? Und wo bitte siehst du in diesem Thread "VORZEICHENBEHAFTETE 8-Bit Werte"?
Ich beziehe mich auf den Threadtitel :-) "2 int8 in ein int16"
Floh schrieb: > Ich beziehe mich auf den Threadtitel :-) > "2 int8 in ein int16" Ups. Ach na ja, wer achtet denn schon auf den Titel. ;-)
Mike schrieb: > Wie wärs mit einer union aus int und einem Array aus 2x int8? Wenn man recht schaut wird da auch nichts anderes dabei rauskommen als ein Casting, Verschieben und Zuweisen.
Bei der Union ist das Ergebnis nicht portabel, ist also mithin von verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes als ein arm-gcc). Auch denn in einem speziellen Fall eine Union ein paar Instruktionen sparen sollte, ist die portable und lesbare Variante vorzuziehen. Den Code mit Casts zu Union und/oder Type-Punning zu verunstalten um ein paar Assembler-Instruktionen rauszuhacken ist nicht wirklich eine gute Idee. In der portablen C99 Variante
1 | #include <stdint.h> |
2 | |
3 | uint16_t glue (uint8_t lo, uint8_t hi) |
4 | { |
5 | return (hi << 8) | lo; |
6 | } |
Gibe es 5 Operationen: Ein Shift, ein Or, zwei 8->16 Promotions und eine 16-Bit Zuweisung. GCC verliert hier leider gerne den Überblick über das Gesamtbild, das sich dem Assembler-affinen Programmierer als 2 8-Bit Zuweisungen darstellt, die bei geschickter Umsetzung des umgebenden Codes sogar entfallen können. Diese Diskrepanz ist es, welche "erfahrene" Entwickler zu Union-Hacks greifen lässt. Aber führt man das Szenario konsequent fort, frogrammiert man Assembler in C und hackt sich hinter jeder verlorenen Instruktion her... Dann sieht der Code irgendwann aus wie Sauerkraut, obwohl die Ursache zwo Assembler-Instruktionen von einer Compiler-Version waren, die schon seit Jahren nicht mehr eingesetzt wird. Und keiner rafft's mehr. Weder was wirklich im Code passiert, nach warum es genau so passiert. Und Ja, das Problem ist im GCC bekannt: PR41076. Und ja, auch GCC-Entwickler wissen wie guter Code auszusehen hat und sind nicht komplett doof ;-)
Wäre es dann Sinnvoll die oben genannte "Funktion" als Inline zu deklarieren? Dann würde man sich doch die Funktionseinprünge sparen, oder? Gruß
Wobei "inline" ja auch nur eine Empfehlung ist und vom Compiler nicht zwangsläufig befolgt wird. Umgekehrt kann der Compiler auch automatisch eine Funktion inline expandieren, wenn es dem Optimizer sinnvoll erscheint. Bei einer derart kurzen und einfachen Funktion kann man eigentlich drauf wetten.
Johann L. schrieb: > Bei der Union ist das Ergebnis nicht portabel, ist also mithin von > verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes > als ein arm-gcc). Das stimmt so nicht.
LittleBigEndian schrieb: > Johann L. schrieb: >> Bei der Union ist das Ergebnis nicht portabel, ist also mithin von >> verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes >> als ein arm-gcc). > > Das stimmt so nicht. Doch, das stimmt. Und wenn man es streng nach ISO C sieht, geht es sogar noch einen Schritt weiter: Da ist nicht einmal definiert, was überhaupt passiert, wenn du solche Schweinereien versuchst.
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.