AVR-GCC/ARM-GCC: least significant bits Vorzeichenrichtig

#3564698
Lesenswert?

Hallo zusammen,
ich habe mal wieder einen C-Knoten im Kopf (naja, es ist diesmal mehr 
ein Zweierkomplementknoten): Ich habe ein Datum, das als 24Bit oder 32 
Bit vorliegt. Davon will ich die letzten beiden Bytes + Vorzeichen 
nutzen, um einen 16-Bit-Integer zu erhalten:
1
int_least24t bigval;
2
uint8_t valLo, valHi;
3
int16_t totalLeast;
4

5
bigval = -1048575;
6

7
valLo = bigval; // ??
8
valHi = bigval < 0 ? (???) : bigval >> 8;
9

10
// Test
11
totalLeast = (valLo + (int16_t) valHi<<8);
Wie berücksichtige ich das Vorzeichen korrekt?

Viele Grüße
W.T.
#3564931
Lesenswert?

Klaus Wachtler schrieb:
> (falls du sicher bist, daß das Ergebnis in 16 Bit
> passt, sonst halt mit Bereichsprüfung vorher)

Ich bin sogar sehr sicher, daß die Zahl nicht in 16 Bit paßt, sondern 
größer ist. Ich will aber nur die letzten Stellen. Sozusagen eine 
Modulo-Operation auf 0x7FFF und dann in zwei Bytes aufteilen. Hm...wenn 
ich drüber nachdenke...

...schlimmstenfalls ist es eine überflüssige Operation, die wegoptimiert 
wird.

Danke für Deine Antwort!
Gast #3565045
Lesenswert?

Ich denke, dass dir mit
1
totalLeast = bigVal % 0x8000
am besten geholfen ist.

Der C-Standard legt nämlich fest:

"When integers are divided, the result of the / operator is the 
algebraic quotient with any fractional part discarded.[footnote: This is 
often called ‘‘truncation toward zero’’.] If the quotient a/b is 
representable, the expression (a/b)*b + a%b shall equal a; otherwise, 
the behavior of both a/b and a%b is undefined."

Daraus folgt, dass das Ergebnis von a%b das Vorzeichen von a hat.
#3565189
Lesenswert?

Mit den Anmerkungen von oben geht es einfacher:
1
int_least24t bigval;
2
uint8_t valLo, valHi;
3
int16_t totalLeast;
4

5
bigval = -1048575;
6

7
bigval %= 0x80000;
8
valLo = *(&bigval);
9
valHi = *(&bigval+1);
10

11
// Test
12
totalLeast = (valLo | (int16_t) valHi<<8);
Die unteren Sachen waren nur zur Erläuterung, wie valLo und valHi 
gelesen werden sollten; letztere brauche ich.

Und es funktioniert auch schon alles.

Danke für die Unterstützung.

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