On Oct 2, 7:34 pm, Kislay <kislaychan...@gmail.comwrote:

Consider the following code snippet

unsigned int i=10;

int j= - 2; // minus 2

if(i>j)

cout<<"i is greater";

else

cout<<"j is greater";

Since i is unsigned , j is greater . I know why , but vaguely . Can

someone please explain the mechanics behind it . Is the unsigned int

converted to signed or is it vice-versa . Also , the same rules would

apply to char as well , right ?

Rule 1: Things get promoted to SIGNED integer types where possible,

otherwise UNSIGNED.

Rule 2: The smaller of the two types involved in the operation has to

change to the bigger type.

Rule 3: If you're left with two types of the same size, but where one

is signed and the other unsigned, they both become unsigned.

Firstly, let's start with the types smaller than int. These types are

as follows:

signed char

unsigned char

signed short

unsigned short

The C Standard guarantees the following:

CHAR_MAX <= SHRT_MAX <= INT_MAX <= LONG_MAX

and also the following:

UCHAR_MAX <= USHRT_MAX <= UINT_MAX <= ULONG_MAX

Before you can do ANYTHING to any of the integer types smaller than

int, they must be promoted. As mentioned before, they promote to

SIGNED where possible, otherwise unsigned. Signed char and signed

short will always promote to signed int on every implementation. As

for unsigned char and unsigned short, they will promote to signed int

on some system, but unsigned int on other systems, depending on

whether all the values of the smaller type can be stored in signed

int. After the promotion of the smaller type takes place, you could

still be left with the following combinations:

1: (unsigned int) + (signed int)

2: (int) + (long)

3: (unsigned int) + (long)

4: (unsigned int) + (unsigned long)

In number 1, both types are the same size but one of them is unsigned,

so they both become unsigned.

In number 2, the int has to become a long.

In number 3, the int has to become a long, but we don't know if all

the values of unsigned int can be stored in a signed long. Therefore,

on some systems this will become an unsigned long, while on others it

will become a signed long. Once the two types are either kind of long,

they will become unsigned long if either of them is unsigned,

otherwise they'll stay as signed long.

In number 4, they'll both become unsigned long.

I suppose the thought process is as follows:

1: Promote things that are smaller than int.

2: Match the sizes (but being careful about whether the small type

will become signed or unsigned of the bigger type).

3: Once the sizes are match, match the signs (if one of them is

unsigned, then they both become unsigned).

Now... as for the rules for converting from unsigned to signed... what

you do is take the max value of the unsigned type, add 1 to it, and

then add it to the signed value.

So let's take -1. Let's pretend that UCHAR_MAX is 255. Therefore we

add as follows:

-1 + (255 + 1) = 255

Therefore the following two are equivalent:

char unsigned c = UCHAR_MAX;

char unsigned c = -1;

As are the following:

short unsigned su = USHRT_MAX - 5;

short unsigned su = -6;

I'll edit your own original code to show you exactly what's going to

happen:

unsigned int i=10;

int j= - 2; // minus 2

unsigned j_changed_to_unsigned = UINT_MAX - 1;

if(i j_changed_to_unsigned)

cout<<"i is greater";

else

cout<<"j_changed_to_unsigned is greater";

You might wanna use printf instead of cout on this newsgroup though ;)

Martin