Forum: Compiler & IDEs Type Cast uint32_t/int32_t in if()


von Pepe (Gast)


Lesenswert?

Hallo.
Hab folgenden Code:

int32_t i = 0;
uint32_t OutputLimit = 32767;

if (i < (OutputLimit * -1))
  { i = -OutputLimit; }
else
if (i > OutputLimit)
  { i = OutputLimit; }

Soll eigentlich nur den Wert i in neg./pos. Richtung limitieren.
Der Vergleich schlägt mit obigen Werten aber fehl, weil ja
i ( = 0x00000000) sicherlich kleiner als OutputLimit ( = 0xFFFF8001) 
ist.
Aber wie muss ich die Typen casten, damits klappt.
Ich steht grad am Schlauch...

Danke.
Pepe.

von Sebastian V. (sebi_s)


Lesenswert?

Wie wäre es wenn du OutputLimit auch als int32_t machst? Signed und 
unsigned Variablen zu mischen führt oft zu bösen Überraschungen, da die 
Regeln dafür relativ kompliziert sind und oft nicht das was man 
erwartet.

von Pepe (Gast)


Lesenswert?

Ja. Das war auch mein Workaround, um weiter zu kommen.
Aber ich hätte trotzdem gern verstanden wie ich casten könnte...

von Luigi (Gast)


Lesenswert?

Ein Cast ist zwar in der Regel immer irgendwie ein work-around aber so 
solltest du auf der sicheren Seite sein:
1
int32_t i = 0;
2
uint32_t OutputLimit = 32767;
3
4
if( i < -(int32_t)(OutputLimit) )
5
  { i = -(int32_t)(OutputLimit); }
6
else if( i > (int32_t)(OutputLimit) )
7
  { i = (int32_t)(OutputLimit); }

Ich habe aber eine Sache mittlerweile gelernt. Signed ist zu bevorzugen!
Es gibt nur wenig Gründe unsigned zu nehmen.
Es passieren 10-mal mehr Fehler bei solchen Sachen durch 
Vorzeichenfehler als durch Überläufe. Und wenn der Wertebereich eines 
32-bit-integer nicht reicht, dann ist der des unsigned auch nur selten 
ausreichend...

von Sebastian V. (sebi_s)


Lesenswert?

Das ist kein Workaround sondern die einzig vernünftige Lösung. Wenn 
OutputLimit ein unsigned int ist und du sowas wie "OutputLimit * -1" 
schreibst dann muss man sich natürlich fragen wie das überhaupt 
ausgerechnet werden soll. Dein OutputLimit ist durch deine Definition 
unsigned und -1 kann aber nur signed sein. In diesem Fall wird das -1 
nun zu unsigned konvertiert und entspricht hier dem Wert 0xFFFFFFFF. Das 
Ergebnis deiner Multiplikation ist dann 0x7FFEFFFF8001 von denen du aber 
nur die letzten 4 Byte siehst. Ähnliche Überlegungen muss man dann auch 
für "-OutputLimit" und was bei einem Vergleich zwischen signed und 
unsigned passiert. Der Vergleich "if (i > OutputLimit)" macht auch nicht 
das was du möchtest, denn für negative i ist die Bedingung auch wahr!

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.