Forum: PC-Programmierung uint32_t zu int16_t?


von Max M. (maxmicr)


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;

: Bearbeitet durch User
von (prx) A. K. (prx)


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.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

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.

von Max M. (maxmicr)


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.

von Wilhelm M. (wimalopaan)


Lesenswert?

Das schaut dann nach einem Template (C++) aus.

von Rolf M. (rmagnus)


Lesenswert?

Max M. schrieb:
>> 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.

Das klingt wenig sinnvoll. Und woran erkennt der Aufrufer eigentlich, ob 
der Wert vorzeichenbehaftet sein soll oder nicht?

von Sebastian V. (sebi_s)


Lesenswert?

Max M. schrieb:
> Das wird etwas schwierig, da die Funktion auch teilweise für
> unsigned-Werte benutzt wird.

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.

von Max M. (maxmicr)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

Das scheint broken-by-design.

Du hast einen Algorithmus und kombinierst signed und unsigned. Alles 
klar.

Du hast einen anderen(!) Algorithmus, bei dem unsigned uns unsigend 
kombiniert wird. Alles klar.

Also entweder überladen falls unterschiedliche Signatur oder template.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Wilhelm M. schrieb:
> Also entweder überladen falls unterschiedliche Signatur oder template.

Ein Template zu verwenden, um verschiedene Integer-Resultate zu 
differenzieren, ist mindestens spannend.

von Wilhelm M. (wimalopaan)


Lesenswert?

Es handelt sich ja wohl um unterschiedliche Algorithmen, daher wäre ein 
Template-Spezialisierung eben anwendbar.

Allerdings: wir haben ja keine Ahnung, was eigentlich gemacht werden 
soll...

von Mark B. (markbrandis)


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 :-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Vllt könnte der TO mal sagen, ob es denn nun C oder C++ sein soll. Dann 
könnte man weiter kommen mit den Vorschlägen:

- unterschiedliche Funktionen/Namen (C)

- überladen, falls unterschiedliche Signatur möglich(C++)

- template spezialisierungen, falls identische Signatur (C++)

- ...

von ui (Gast)


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.

von Mark B. (markbrandis)


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.

von tictactoe (Gast)


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.

von Rolf M. (rmagnus)


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).

von A. S. (Gast)


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.

von Dirk B. (dirkb2)


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.

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.