uint32_t zu int16_t?

OP #4821895
Lesenswert?
• ▲
▼
Guten Abend,

ich hab eine allgemeine Funktion geschrieben, die einen uint32_t-Wert 
zurück gibt. Es kann jedoch auch vorkommen, dass es sich um eine 
negative (also einen signed Wert) Zahl handelt. Meine Frage ist nun, ob 
das ganze einfach durch einen expliziten Typecast gelöst werden kann? 
Z.B. so:
1
uint32_t result = myFunc();
2
int16_t signedValue = (int16_t)result;
#4821898
Lesenswert?
• ▲
▼
Das Verhalten vorzeichenbehafteter Typen bei Überlauf ist offiziell 
undefiniert. Du wirst sehr wahrscheinlich einfach bloss die unteren 16 
Bits kriegen, mit und ohne Cast.

Der Cast wird dir ggf. eine aggressiv eingestellte Warnung ersparen, 
aber typischerweise nichts am erhaltenen Wert ändern. Eine Sättigung zu 
grosser oder kleiner Werte auf die Limits erfolgt nicht.
OP #4821902
Lesenswert?
• ▲
▼
Mark B. schrieb:
> Max M. schrieb:
>> Guten Abend,
>>
>> ich hab eine allgemeine Funktion geschrieben, die einen uint32_t-Wert
>> zurück gibt. Es kann jedoch auch vorkommen, dass es sich um eine
>> negative (also einen signed Wert) Zahl handelt.
>
> Dann muss die Funktion eben einen vorzeichenbehafteten Wert zurückgeben.

Das wird etwas schwierig, da die Funktion auch teilweise für 
unsigned-Werte benutzt wird. Schade, ich dachte ich könnte das alles mit 
einer Funktion abbilden.
#4822503
Lesenswert?
• ▲
▼
Max M. schrieb:
> Rolf M. schrieb:
>> Das klingt wenig sinnvoll. Und woran erkennt der Aufrufer eigentlich, ob
>> der Wert vorzeichenbehaftet sein soll oder nicht?
>
> Gar nicht, der Aufrufer bin nur ich. Ich lese Werte aus verschiedenen
> Registern, laut Datenblatt ist ein Wert als short zu interpretieren, die
> restlichen jedoch als unsigned short.

Man muss ja nicht zwingend eine einzige Funktion schreiben, die alle 
Fälle abdeckt. Man darf dies sogar mit zwei oder mehr Funktionen 
erledigen :-)
Gast #4822509
Lesenswert?
• ▲
▼
Sebastian V. schrieb:
> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
> signed zu bleiben.

Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau 
andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher 
bin signed zu brauchen nutz ich das auch.
#4822513
Lesenswert?
• ▲
▼
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Sehe ich auch so.
Gast #4822996
Lesenswert?
• ▲
▼
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Z.B. ist ein Überlauf von signed-Variablen "undefined behavior". Der 
Compiler darf also annehmen, dass das nicht auftritt. Was wesentlich 
mehr Gelegenheiten zum Optimieren zur Folge hat.
#4823006
Lesenswert?
• ▲
▼
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Das kann zu unerwarteten Problemen bei Berechnungen und Vergleichen 
führen, wenn man dann doch einen Signed-Wert braucht und den dann mit 
einem Unsigned vergleicht. So was typisches ist z.B. eine Größenangabe. 
Klar, die Maximalgröße ist doppelt so groß, wenn man unsigned nimmt. 
Braucht man aber einen Offset zwischen zwei Elementen, kann dieser auch 
negativ sein, und es ist nicht mehr in jedem Fall möglich, einen Offset 
zwischen zwei beliebigen Elementen anzugeben - zumindest nicht ohne 
einen Wrap-Around.
Man kriegt bei Vergleichen oder Berechnungen mit gemischt signed und 
unsigned auch eine Warnung vom GCC deswegen.
Das hat sogar dazu geführt, dass Sprachen wie z.B. Java unsigned-Typen 
nicht mal kennen (was ich aber auch für Blödsinn halte).
Gast #4823066
Lesenswert?
• ▲
▼
Rolf M. schrieb:
> Das kann zu unerwarteten Problemen bei Berechnungen und Vergleichen
> führen, wenn man dann doch einen Signed-Wert braucht und den dann mit
> einem Unsigned vergleicht.

Das stimmt. Allerdings gilt auch das:
tictactoe schrieb:
> Z.B. ist ein Überlauf von signed-Variablen "undefined behavior".

Damit ist aber "offiziell" kein free-running-counter (a la Systicker) 
mehr möglich.

Zudem ist jede Division durch 2^n eine echte Division (statt shift), da 
die Zahl ja negativ sein könnte.

Bitte versteh mich nicht falsch, ich finde diese 
signed/unsigned-Probleme als mit die schlimmsten bei C. Wie man sich 
auch entscheidet, es holt einen ein.
#4823146
Lesenswert?
• ▲
▼
Max M. schrieb:
> Gar nicht, der Aufrufer bin nur ich. Ich lese Werte aus verschiedenen
> Registern, laut Datenblatt ist ein Wert als short zu interpretieren, die
> restlichen jedoch als unsigned short.

Warum gibst du dann keinen signed Typen zurück, der größer als unsigned 
short ist? Also long?


Das Problem gibt es doch schon bei der Standardfunktion getc.
Die liefert Zeichen als positive int-Werte zurück, obwohl char selber 
häufig signed ist.
Spielt bei ASCII keine Rolle, aber bei den allermeisten Erweiterungen 
gibt es Probleme.

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