Ich habe diese Seite nach einer Antwort durchsucht und viele Antworten auf einen unsignierten / signierten Vergleich gefunden, aber dieses Problem besteht darin, dass nur vorzeichenlose Parameter verglichen werden, aber trotzdem funktioniert es lustig.
Das Problem mit dem folgenden Code ist, dass die erste if
-stat nicht auftritt ("Hallo"), wo die zweite ("Welt") tut. Dies habe ich interpretiert, da die Berechnung, die innerhalb der if
-statement durchgeführt wird, eine negative Zahl erzeugt, aber die exakt gleiche Berechnung, die mit dem in einer Variable gespeicherten Ergebnis durchgeführt wurde, nicht funktioniert (obwohl das Ergebnis in einer signierten Variable gespeichert wird).
Der verwendete Compiler ist gcc 4.4.
%Vor% Kann jemand das für mich erklären und vielleicht eine Lösung für eine Korrektur finden, so dass die erste if
-Anweisung auch funktioniert?
Im Ausdruck:
%Vor% (u16_varLow - u16_varHigh)
wird zu einem int
hochgestuft und zu -65525 ausgewertet. Die Lösung für Ihr Problem besteht darin, auf einen unsignierten Typ zu konvertieren, wie Sie es in dem "Wird eingeben" -Code tun.
Der Grund dafür, dass s16_Res1 = u16_varLow - u16_varHigh;
11 ergibt, ist, dass das Ergebnis der Subtraktion, -65525, nicht in einen Short passt.
In den anderen Antworten haben wir das gesehen
%Vor% für Sie (mit 16 bit short
und 32 bit int
) entspricht
und somit sein Ergebnis ist int
value -65525
. Also die Zuordnung
entspricht
%Vor% was in Ihrem Fall von 16 bit short
zu undefiniertem Verhalten führt. Sie haben nur Pech, dass Ihr Compiler stattdessen 11
zuweisen möchte. (Pech, weil ich denke, dass es besser ist, früh zu versagen.)
Im Gegensatz dazu
%Vor% ist eine gültige Zuweisung, da u16_Res1
vom Typ ohne Vorzeichen ist und die Arithmetik von vorzeichenlosen Typen modulo mit der entsprechenden Potenz von zwei ist.
Bei den "üblichen arithmetischen Konvertierungen" werden Typen, die kleiner als int
sind, entweder in int
oder in unsigned int
umgewandelt, bevor sie in den meisten Ausdrücken verwendet werden. Die Regel lautet: Wenn int
alle Werte des kleineren Typs darstellen kann, wird sie zu int
; Andernfalls wird es zu unsigned int
hochgestuft. Dies wird oft als eine Art Warze angesehen, da es in vielen Fällen dazu führt, dass die Werte unsigned char
und unsigned short
auf int
hochgestuft werden.
Genau das sehen Sie - u16_varLow
und u16_varHigh
und (unsigned short)5
werden alle vor der Subtraktion und dem Vergleich zu int
hochgestuft, was dann mit int
geschieht. Wenn Sie sicher sein wollen, dass ein Ausdruck vorzeichenlose Arithmetik verwendet, müssen Sie dies in unsigned int
, nicht unsigned short
:
Die erste, if( (u16_varLow - u16_varHigh) > (unsigned short)5 )
, wird niemals übergeben, da (u16_varLow - u16_varHigh)
eine negative Zahl zurückgibt, weil sie als ganze Zahl behandelt wird. Die zweite wirft die gleiche negative Zahl, kurz vorzeichenlos, deshalb vergeht sie.
Hinweis - Sie wissen, dass dies plattformabhängig ist, oder? Die Größe von short
, int
usw. hängt von der konkreten Plattform ab.
Tags und Links c comparison if-statement unsigned