Zweierkomplemente zusammenführen

#1713580
Lesenswert?

fliege schrieb:
> Moin.
> Ich möchte einen 32-Bit-Wert, bestehend aus 4 Bytes zusammenführen.
>
> Bei zwei Bytes ist das ja ganz einfach:
>
> Wert = Byte_1 << 8 | Byte_2;
>
> Aber wie geht das jetzt mit 4 Bytes?

Im Prinzip genauso. Man muss nur aufpassen, das man rechtzeitig die 
Kurve zu 32 Bit kriegt.
1
Wert = (uint32_t)Byte_1 << 24 |
2
       (uint32_t)Byte_2 << 16 |
3
       Byte_3 << 8            |
4
       Byte_4;
Persönliche Seite #1713591
Lesenswert?

fliege schrieb:

> Bei zwei Bytes ist das ja ganz einfach:
> Wert = Byte_1 << 8 | Byte_2;
              ^             ^

Kennst du die Byte-Reihenfolge (Endianess) auf deinem System oder es ist 
zufällig richtig? http://de.wikipedia.org/wiki/Byte-Reihenfolge

In deinem Betreff steht Zweierkomplemente
http://de.wikipedia.org/wiki/Zweierkomplement

Wenn Byte_1, Byte_2... tatsächlich Zahlen mit Vorzeichen sind, dann 
würde ich statt Bitoperationen die Rechenoperationen benutzen und die 
"Optimierung" dem Compiler überlassen.

int8_t Byte_1, Byte_2;
int16_t Wert = Byte_1 * 256 + Byte_2;
Gast #1713600
Lesenswert?

Dann habe ich mich vielleicht in der Fragestellung falsch ausgedrückt. 
Die Bytes bekomme ich ine einem CAN-Telegramm und weiß daher welches 
Byte das MSB und welches das LSB ist.

Ich habe B1 B2 B3 B4 wobei B1 das MSB und B4 das LSB ist.

Jetzt brauche ich eine Operation, die mirt aus den vier Bytes einen Wert 
zaubert. (So wie ich das oben mir 2 Bytes beschrieben habe.)
#1713664
Lesenswert?

fliege schrieb:
> Warum ist bei Byte 1 und Byte 2 eine Variablendeklaration von uint32t
> vorgesetzt und bei Byte 3 & 4 nicht? Oder war das nicht Absicht?

Doch das ist Absicht
1) das ist keine Variablendeklaration sondern ein Cast
2) ist der notwendig, damit ich den Compiler zwinge, die Operation
   in 32 Bit auszuführen.
   Tu ich das nicht, dann macht er eine int Operation (also 16 Bit)
   daraus und dann fällt mir links alles raus.

3) solltest du dir ein C-Buch zulegen
#1713687
Lesenswert?

fliege schrieb:
> Dann habe ich mich vielleicht in der Fragestellung falsch ausgedrückt.
> Die Bytes bekomme ich ine einem CAN-Telegramm und weiß daher welches
> Byte das MSB und welches das LSB ist.
>
> Ich habe B1 B2 B3 B4 wobei B1 das MSB und B4 das LSB ist.
>
> Jetzt brauche ich eine Operation, die mirt aus den vier Bytes einen Wert
> zaubert. (So wie ich das oben mir 2 Bytes beschrieben habe.)

Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege 
damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.
Moderator Persönliche Seite #1713723
Lesenswert?

Kluchscheißender Kluchscheißer schrieb:

> Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege
> damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.

Geht, aber man muss dann die Prozessor-Byteorder beachten. Vom CAN-Bus 
kommen die vier Bytes mit MSB first. Das kann vielleicht gerade die 
"falsche" Byteorder für den Prozessor sein.

Multiplikation mit 2^24, 2^16, 2^8 und 2^0 und anschließende Addition 
der 4 Werte wäre da schon das portabler, weil dann das Byteordering des 
Prozessors vollkommen egal ist.

Gruß,

Frank
#1713809
Lesenswert?

Frank M. schrieb:
> Kluchscheißender Kluchscheißer schrieb:
>
>> Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege
>> damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.
>
> Geht, aber man muss dann die Prozessor-Byteorder beachten. Vom CAN-Bus
> kommen die vier Bytes mit MSB first. Das kann vielleicht gerade die
> "falsche" Byteorder für den Prozessor sein.

Naja, ich denke, die kann man vorwärts wie rückwärts in das Array mit 
Bytes legen.

>
> Multiplikation mit 2^24, 2^16, 2^8 und 2^0 und anschließende Addition
> der 4 Werte wäre da schon das portabler, weil dann das Byteordering des
> Prozessors vollkommen egal ist.

Das mag sein, jedoch habe ich vorhin erst gelesen, dass die Portabilität 
von C auf Mikrocontrollern eine Illusion ist:
Beitrag "Re: Code von Atmel Mega8 auf ATtiny13"
Und der Mann, der das schrieb, hat wirklich Ahnung...

>
> Gruß,
>
> Frank

;-)
#1713823
Lesenswert?

Kluchscheißender Kluchscheißer schrieb:

> Das mag sein, jedoch habe ich vorhin erst gelesen, dass die Portabilität
> von C auf Mikrocontrollern eine Illusion ist:

Das ist keine Entschuldigung für miserablen Code.

Nicht, wenn man mehr macht als ein paar LEDs aus- und einzuschalten. Ich 
habe mir ein paar I/O-Module für UART, CAN, I2C, ... gebaut, die zwar 
auf AVR, LPC2000, STM32 alle verschieden implementiert sind, aber deren 
Interface nach oben weitgehend gleich ist. Darauf aufbauender Code ist 
folglich nicht mehr vom Controller abhängig und Portabilität wird ein 
Thema.

Und erst recht nicht, wenn man mit Kommunikationsprotokollen arbeitet. 
Wenn man damit nicht nur Selbstgespräche führt, dann ist irgendwann eine 
Node dabei, deren Byteorder nicht zu den übrigen Nodes passt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren