"Frederick Gotham" <fg*******@SPAM.comwrote:

I just want to clarify my understanding of arithmetic and comparison

between two different integer types.

Phase (1): Integer Promotion

----------

All of the following types always get promoted to "signed int":

signed char

signed short

All of the following types get promoted to "signed int" if it has

sufficient range on the platform; otherwise, they go to "unsigned int".

char

unsigned char

unsigned short

Phase (2): Now working with "int" and upwards

----------

Now everything is one of the following types:

signed int

unsigned int

signed long

unsigned long

That leaves us with 10 possibilities. The first four are straight-forward:

(1) signed int + signed int

(2) unsigned int + unsigned int

(3) signed long + signed long

(4) unsigned long + unsigned long

The following involve the same type, but different signedness. Am I right

in thinking that they both become "unsigned int" in (5), and both become

"unsigned long" in (6)?

(5) signed int + unsigned int

(6) signed long + unsigned long

Then there's two different types which have the same signedness. Would I be

right in thinking that they both become signed long in (7), and both become

unsigned long in (8)?

(7) signed int + signed long

(8) unsigned int + unsigned long

Now here's the dirty ones which I'm least sure about. What happens in (9)

and (10)? Are (9) and (10) implementation-specific depending on whether

numeric_limits<long>::digits numeric_limits<int>::digits?

(9) signed int + unsigned long

(10) unsigned int + signed long

The C++ standard, section 5, paragraph 9 reads:

Many binary operators that expect operands of arithmetic or enumeration

type cause conversions and yield result types in a similar way. The purpose

is to yield a common type, which is also the type of the result. This

pattern is called the usual arithmetic conversions, which are defined as

follows:

— If either operand is of type long double, the other shall be converted

to long double.

— Otherwise, if either operand is double, the other shall be converted to

double.

— Otherwise, if either operand is float, the other shall be converted to

float.

— Otherwise, the integral promotions (4.5) shall be performed on both

operands.54)

— Then, if either operand is unsigned long the other shall be converted

to unsigned long.

— Otherwise, if one operand is a long int and the other unsigned int, then

if a long int can represent all the values of an unsigned int, the unsigned

int shall be converted to a long int; otherwise both operands shall be

converted to unsigned long int.

— Otherwise, if either operand is long, the other shall be converted to long.

— Otherwise, if either operand is unsigned, the other shall be converted to

unsigned.

[Note: otherwise, the only remaining case is that both operands are int ]

So most of your cases are set in concrete:

In your cases 1,2,3,4 no conversions would occur.

In your case 5, both operands would be converted to unsigned int

In your cases 6, 8, 9, both operands would be converted to unsigned long.

In your case 7, both operands would be converted to signed long

The only case that's implimentation dependent is your case 10.

If long can represent the values, both operands will be converted to long.

However, on most modern 32-bit PCs, long can NOT represent all the values

of unsigned int. Usually the ranges are:

long: -2147483648 to 2147483647

unsigned: 0 to 4294967296

On such machines, in your case 10, both operands will be converted to

unsigned long int, which is usually identical in range to unsigned int.

So any negative values will be converted to very large positive values.

Depending on the application, that could be a disaster or a don't-care.

--

Cheers,

Robbie Hatley

Tustin, CA, USA

lonewolfintj at pacbell dot net (put "[ciao]" in subject to bypass spam filter)

http://home.pacbell.net/earnur/