What are the general rules for comparing different data types in C?
Lets say I have the following scenarios:
int i = 10;
short s = 5;
if (s == i){
do stuff...
} else if (s < i) {
do stuff...
}
When C does the comparison does it convert the smaller data type, 开发者_Go百科in this case short to int or does it convert the data type on the right to the data type on the left? In this case int to short?
This is governed by the usual arithmetic conversions. For simple cases, the general rule of thumb is that the type with "less" precision is converted to match the type with "more" precision, but it gets somewhat complex once you start mixing signed
and unsigned
.
In C99, this is described by section 6.3.1.8, which I include here for your convenience:
First, if the corresponding real type of either operand is
long double
, the other operand is converted, without change of type domain, to a type whose corresponding real type islong double
.Otherwise, if the corresponding real type of either operand is
double
, the other operand is converted, without change of type domain, to a type whose corresponding real type isdouble
.Otherwise, if the corresponding real type of either operand is
float
, the other operand is converted, without change of type domain, to a type whose corresponding real type isfloat
.Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
- If both operands have the same type, then no further conversion is needed.
- Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
- Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
- Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
I've highlighted the part that applies to your particular example.
The concept of integer conversion rank is defined in section 6.3.1.1, and it basically describes what you might expect (that types with less precision have a lower rank than types with more precision).
From Type Conversions:
The set of implicit conversions on page 44, though informally stated, is exactly the set to remember for now. They're easy to remember if you notice that, as the authors say,
the `lower' type is promoted to the `higher' type,'' where the
order'' of the types is
char < short int < int < long int < float < double < long double
That rule is easy to remember - "lower to higher" - but regarding signed and unsigned integer types it doesn't help much, those are nicely explained in Oli's post. But it's easy to remember and helps you in most cases.
As a general rule, C will not compare two values if they are not the same type and will never implicitly convert a variable to a type with less precision. In your sample code, the short
is promoted to an int
, which is equivalent to writing:
int i = 10;
short s = 5;
if ((int)s == i){
do stuff...
} else if ((int)s < i) {
do stuff...
}
This will do exactly what you expect, but the same is not true of signed/unsigned comparison.
Datatypes are an abstraction of sorts .. as far as computer is concerned there are no int
or short
. There is memory and there is data.
When you say int x
, you are saying to a computer "give me enough bytes to store an int", when you say short y
, you are saying ... you guessed it.
short
, as you would expect takes less bytes then an int
and therefore may (and often does) contain data in the adjacent bytes. When comparing data of different types the issue is "will adjacent bits cause skewed results or not?"
Whenever you compare two different datatypes you really are comparing bits stored in two different locations. Max number of individual bits stored to represent the data need to be the same size for a comparison to work
Casting is used to help with this.
精彩评论