Forum: Compiler & IDEs signed typecast 32-bit in 16-bit


von Sven (Gast)


Lesenswert?

Hallo,

ich habe einen Fehler mit dem cast gemacht. Würde aber gerne etwas 
erfahren, was ich da genau gemacht habe.

Ich habe eine Variable signed 16-bit:
int16_t s16fooword

In einer Rechnung habe ich aber folgendes gemacht:
s16fooword = (int32_t) (F_CPU/60)*u16rpm*s16multiplier;

wobei rmp ein uint16_t ist und s16multiplier int16_t (und daher auch 
negativ)

Der Wert der gecasteten Zahl hat gestimmt, nur war das Vorzeichen weg 
bzw. die Zahl war positiv, obwohl s16multiplier negativ ist.

Was genau ist da passiert?
Richtig wollte ich eigentlich so casten:

s16fooword = (int16_t) ((F_CPU/60)*u16rpm*s16multiplier;

Danke.

von (prx) A. K. (prx)


Lesenswert?

Aus
   (int32_t) (F_CPU/60)*u16rpm*s16multiplier
also
   ((int32_t)(F_CPU/60) * u16rpm) * s16multiplier
wird vom Typ her
   (int32_t * uint16_t) * int16_t
und danach
   int32_t * int16_t
und folglich sollte das Vorzeichen erhalten bleiben.

Hingegen wird aus
   (int16_t) ((F_CPU/60)*u16rpm*s16multiplier)
vom Typ her
   (int16_t) ((? * uint16_t) * int16_t)
und da hängt es von ? ab, ob das Vorzeichen bleibt oder nicht.

von Peter D. (peda)


Lesenswert?

Unsigned ist das höhere Format.
Unsigned * signed wird also in unsigned ausgeführt.

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:
> Unsigned * signed wird also in unsigned ausgeführt.

Unsigned hat nur dann Vorrang gegenüber signed, wenn es mindestens 
gleich gross ist, und nicht kleiner als int.

Also gilt:
  unsigned int * signed int => unsigned int
Es gilt nicht, wenn die signed Seite grösser als die unsigned Seite ist:
  uint16_t * int32_t => int32_t
Auch nicht, wenn beide Seiten kleiner sind als int:
  uint8_t * int8_t => int

von Peter D. (peda)


Lesenswert?

Das war auch nur eine Vermutung.
Wir wissen ja nicht, wie der wirkliche Code aussieht.

Es besteht unerklärlicher Weise immer eine riesen Angst bei den 
Fragestellern, den exakten Code als Anhang einsehen zu lassen.

von Sven (Gast)


Lesenswert?

Ich habe den Code leider im Moment nicht hier auf der Arbeit und habe 
das nur aus dem Kopf zusammengeschrieben.
F_CPU ist per Makro als 8000000UL definiert.

Aber die Ausführungen haben mir geholfen zu verstehen, wie das mit dem 
Verwerten der Datentypen und Casten läuft

von (prx) A. K. (prx)


Lesenswert?

Sven schrieb:
> F_CPU ist per Makro als 8000000UL definiert.

Im UL hast du die Antwort für den Fall
  (int16_t) ((F_CPU/60)*u16rpm*s16multiplier

NB: Syntaxfehler machen stets misstrauisch.

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
Noch kein Account? Hier anmelden.