Hallo,
Hoffe kann mir einer hier weiterhelfen.
Ich will 2 Char Zahlen zu einer short verbinden, habs auch hinbekommen
und so realisiert:
1
unsignedchara=0x76;
2
unsignedcharb=0x02;
3
unsignedshortc=(b<<8)|a;//c= 0x276
Jedoch wird durch diese Methode zuviel Rechenlaufzeit benutzt. Kennt
jemand vielleicht eine andere Möglichkeit ohne zu shiften diese 2 Zahlen
zu einer zu verbinden.
Danke.
Peter schrieb:> Kennt> jemand vielleicht eine andere Möglichkeit ohne zu shiften diese 2 Zahlen> zu einer zu verbinden.
Mit einer union geht das ohne eine Rechenoperation, ist aber wegen
big/little endian problem nicht portabel.
Peter schrieb:> Jedoch wird durch diese Methode zuviel Rechenlaufzeit benutzt.
WIE hast du das festgestellt? WELCHEN Compiler hast du da verwendet?
> Kennt jemand vielleicht eine andere Möglichkeit ohne zu shiften> diese 2 Zahlen zu einer zu verbinden.
Ja: dein Compiler.
ok, vielleicht täusche ich mich ja auch, sagen wir so, gibt es eine
andere Methode als mit shiften, und High byte und Low byte, zwei char
Variablen zu einer short zu verknüpfen. Danke.
Danke für die Antwort, das funktioniert, aber du hast recht, ist halt ne
andere Form von shiften. Gibt es da eine Möglichkeit mit Arrays zusammen
zufügen.
Peter schrieb:> ok, vielleicht täusche ich mich ja auch, sagen wir so, gibt es eine> andere Methode als mit shiften, und High byte und Low byte, zwei char> Variablen zu einer short zu verknüpfen. Danke.
Ich nehme mal an, dass Dein tatsächlicher Code NICHT so aussieht, denn
das obige optimiert Dir der gcc zu
c = 0x0276
Schneller gehts nicht.
Also jetzt mal Tacheles:
1. Welcher µC?
2. Welcher Compiler? Wirklich gcc?!?
3. Wie sieht Dein Quellcode tatsächlich aus?
4. Wieviel Rechenzeit wird verbraten?
Ohne die Beantwortung dieser Fragen ist weitere Hilfe unmöglich.
Peter schrieb:> und wie funktioneirt das mit einer union, kenne ich nicht.
Lies ein C-Buch.
Wirklich. Da drin steht, was eine union ist, und das musst Du, um es
benutzen zu können, auch begreifen.
Deswegen bringen irgendwelche zusammenkopierten Codeschnipsel aus
irgendwelchen "Tutorials" auch nichts.
Brian Kernighan & Dennis Ritchie, "Programmieren in C", 2. Ausgabe,
Hanser-Verlag.
Ob Du da Multiplikation oder Shiften hinschreibst, ist egal. Der
Compiler kümmert sich darum, dass das Ergebnis mit den zur Verfügung
stehenden Maschinenbefehlen möglichst effizient erreicht wird. Nur weil
im C-Code ein Shift da steht, wird daraus also nicht zwangsläufig auch
ein Shift-Maschinenbefehl werden. Der Compiler kann also durchaus
erkennen, was Du da vorhast, und kopiert einfach das Byte an die
richtige Stelle.
Das ganze steht ja sowieso nicht für sich. Die Variablen liegen entweder
im Speicher oder schon in CPU-Registern und das Ergebnis wird auch
irgendwie weiterverarbeitet. Vielleicht muss dabei im Endeffekt nicht
mal umkopiert werden, gerade wenn es ein 8-Bit-Prozessor ist.
Schreib den Code also so, dass man ihn gut versteht und lass den
Compiler den Rest machen. Die Stelle ist garantiert kein
Geschwindigkeitsengpass.
Peter schrieb:> Jedoch wird durch diese Methode zuviel Rechenlaufzeit benutzt.
Beweisen!
> eine andere Möglichkeit ohne zu shiften
Wie xfr richtig schreibt, bedeutet der Operator
[C]
(b << 8)
[C/]
nicht zwangsläufig, daß irgendjemand anfängt, irgendetwas zu schieben.
Du sagst dem Compiler damit:
"Interpretierte b um 8 Bits nach links geschoben"
Der Compiler kennt da mitunter tolle Tricks, wie z.B. den "SWAP"...
Der ARM shiftet gern. Er tut das lieber und schneller als auf das RAM
zuzugreifen, wie es bei der Union-Methode vermutlich der Fall wäre.
Probier doch einfach mal verschiedene Methoden aus und schau dir den
generierten Assemblercode an. Ich bin mir fast sicher, dass du keine
bessere als die Shift-Methode finden wirst, die zudem gut lesbar und
nicht von der Endianess abhängig ist.
Der gcc ersetzt Shifts von Variablen, die einen bekannten Wert haben
(und die Variablen a und b in obigem Quellcode sind bekannt!) direkt
durch eine Konstante. Der TO muss sich irren. Sein Problem muss woanders
liegen.
Peter schrieb:> und wie funktioneirt das mit einer union, kenne ich nicht.
Die union packt dir die beiden chars in Speicherzellen nebeneinander.
Gleichzeitig entsteht daraus dann ein 2 byte Wert (z.B. uint) daraus.
Das braucht überhaupt keine Rechenoperation da die char Werte
"strukturbedingt" einen int bilden.
Da aber die Compiler die int Werte in unterschiedlicher Bytereihenfolge
abbilden (Lowbyter oder Highbyte zuerst) ist es nicht portabel.
Jens Martin schrieb:> Da aber die Compiler die int Werte in unterschiedlicher Bytereihenfolge> abbilden (Lowbyter oder Highbyte zuerst) ist es nicht portabel.
War das nicht so, dass die CHARs auch mal fix an 32 od. 64 Bit
ausgerichtet werden können?