I have searched this site for an answer and found many responses to unsigned/signed comparison but this problem is that only unsigned parameters are compared but still it works funny.
The problem with the following code is that the first if
-statment does not happen ("hello") where as the second ("world") does. This I have interpreted as the calculation that is done inside the if
-statment generates a negative number but the exact same calculation done with the result saved to a variables does not (even though the result is being saved to a signed variable).
The compiler used is gcc 4.4.
unsigned short u16_varHigh;
unsigned short u16_varLow;
unsigned short u16_Res1;
signed short s16_Res1;
u16_varHigh = 0xFFFF;
u16_varLow = 10;
u16_Res1 = u16_varLow - u16_varHigh; // response is 11 as expected
s16_Res1 = u16_varLow - u16_varHigh; // response is 11 as expected
// Does not enter
if( (u16_varLow - u16_varHigh) > (unsigned short)5 )
{
printf( "hello" );
}
// Does enter
if( (unsigned short)(u16_varLow - u16_varHigh) > 5 )
{
printf( "world" );
}
Can anyone explain this for me and perhaps come up with a solution for a fix so that the first if
-statement works as well?
In the expression:
if( (u16_varLow - u16_varHigh) > (unsigned short)5 )
(u16_varLow - u16_varHigh)
will be promoted to an int
and evaluate to -65525. The fix for your problem is to cast to an unsigned type, like you do in the "Does enter"-code.
The reason s16_Res1 = u16_varLow - u16_varHigh;
yields 11 is that the result of the subtraction, -65525, doesn't fit in a short.
In the other answers we have seen that
u16_varLow - u16_varHigh
for you (with 16 bit short
and 32 bit int
) is equivalent to
(int)u16_varLow - (int)u16_varHigh
and thus its result is the int
value -65525
. Thus the assignment
s16_Res1 = u16_varLow - u16_varHigh;
is equivalent to
s16_Res1 = -65525;
which in your case of 16 bit short
yields "undefined behavior". You are just unlucky that your compiler decides to assign 11
, instead. (Unlucky because I think that it is better to fail early.)
In contrast to that
u16_Res1 = -65525;
is a valid assignment since u16_Res1
is of an unsigned type and arithmetic of unsigned types is modulo the appropriate power of two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With