-3

I tried older post but not able to understand following behavior.
https://stackoverflow.com/questions/12295168/c-signed-unsigned-mismatch
unsigned int and signed char comparison

#define T       long  

int main()  
{         
 unsigned T a;  
 T b;  
 a=1;  
 b=-1;      
 if(a>b)    
    printf("True\n");  
 else  
    printf("False\n");  

 return 0;  
}  

I tried above code for T=char, short int and long.
observed output for char and short is TRUE, while for int and long is FALSE. I tried above code in Ubuntu gcc.
Can anyone explain, why am I getting different output for different data types?

Community
  • 1
  • 1
Embedded Programmer
  • 519
  • 4
  • 8
  • 22
  • 7
    Duplicate hundreds of times over. What didn't you understand about the answers to the questions you linked? – Carl Norum Jul 10 '13 at 04:59
  • 2
    Please don't do vote this question just because it's a duplicate. This question is actually well written compared to the other floods of questions here. – Cole Tobin Jul 10 '13 at 05:05
  • Can I refer you to [this](http://stackoverflow.com/questions/17312545/type-conversion-unsigned-to-signed-int-char/17312760#17312760) link? – Nobilis Jul 10 '13 at 05:12

2 Answers2

3

When testing against the signed b value for char and short the value gets widen to an int and this replicates the sign bit whereas for the a value the signed bit is not replicated.

Thus for char the if becomes if (0x00000001 > 0xFFFFFFFF) and this is true (assuming a 32 bit int).

But when using an unsigned that is an int or bigger the test is done using an unsigned comparision.

Richard Schneider
  • 34,944
  • 9
  • 57
  • 73
  • i tried, if((unsigned int)a>(int)b) , every time i am getting FALSE output, irrespective of data type of a and b variable. why is it behaving like this? – Embedded Programmer Jul 15 '13 at 04:31
1

char is promoted to int in cases such as yours where you compare two variables.

Let's see what happens underneath for char types:

a is promoted to an int and it remains as 1. b is also promoted to an int, the sign is preserved and it also remains as -1. Is 1 > -1? Yes!

And what about int types:

As there as an unsigned operand involved all of them will be converted to unsigned. In the case of a which is already unsigned 1 is preserved as it is. However, b is signed and therefore we need to lose the sign.

Due to the underlying bit representation, on a 32 bit machine, -1 actually has the same bits as 4294967295. And you end up comparing if 1 is bigger than 4294967295. I think the answer is obvious.

Nobilis
  • 7,310
  • 1
  • 33
  • 67
  • i tried, if((unsigned int)a>(int)b) , every time i am getting FALSE output, irrespective of data type of a and b variable. why is it behaving like this? – Embedded Programmer Jul 15 '13 at 04:33
  • @EmbeddedProgrammer When you compare a signed and an unsigned operand, the signed one is **always** converted to unsigned and no amount of casting will change this. If you want to get 'True' you need to cast the unsigned operand into signed - `if ((int)a > (int)b)`. Or for example have the following values for `a` and `b`:`a=2223456789; b=-2123456789; if ((unsigned)a > (int)b)`. Always take into account the binary representation underneath. – Nobilis Jul 15 '13 at 05:30
  • Nobilis, why does if(a>b) gives TRUE for char and unsigned char. As you explained it is converted to int, but when i convert a and b into hex value the a=1 and b=-2147483648.it is ok,but when i try for int or long. then a=1 and b=-2147483648. then why am i getting FALSE? it should be TRUE. – Embedded Programmer Jul 15 '13 at 06:11
  • @EmbeddedProgrammer Can you please post your assignments as code, I'm not sure what you mean. Are you assigning -2147483648 to a `char`? – Nobilis Jul 15 '13 at 06:18
  • Hi Nobilis, i have given above code for #define T long in first question. – Embedded Programmer Jul 15 '13 at 09:04
  • @EmbeddedProgrammer But you talk about converting to hex values and assigning `b` -2147483648, this is not in the code and I'm not sure what you mean. Anyway let's assume you have `unsigned int a = 1;` and `int b = -2147483648;`. You are getting FALSE because (again) when comparing signed and unsigned, the signed is converted to unsigned. Underneath -2147483648 becomes 2147483648 and this is bigger than 1. You can prove this by running the following: `printf("%u ", -2147483648);` – Nobilis Jul 15 '13 at 09:20