I haven't been able to find anything in my books about math functions using combinations of variable types. Examples:
long = long / int long = 8000000 / int int = 8000000 / int unsigned char = int
I have had problems more than once with this - what sometimes seems to me that it should work often doesn't. Is it at all compiler dependent? Where can I find good information on the subject?
Thx Scott Kelley
Didn't find your answer? Ask the community — no account required.
I
Ian Bell
Isn't that what casting is for??
ian
D
Dave Hansen
The C standard does spell this all out. Whether your compiler complies (especially if it targets a small, e.g, 8-bit, procesor) is another matter. If the standard is to abstruse, Harbison and Steele's "C: A Reference Manual" is excellent. Look for "The Usual Conversions."
Summary:
1) Integer types have rank. Each signed in type has the same rank as the corresponding unsigned type (as well as plain char). long long outranks long outranks int outranks short outranks char outranks _Bool
1) There are no integer expressions narrower than int. If both operands are integer types of lower rank than int, they are converted to int before the operator is applied, unless int cannot represent all possible resulting values, in which case they are converted to unsigned int.
3) Before an operator is applied, the following conversions are applied if the operands differ in type:
if one operand is long double convert other to long double else if one operand is double convert other operand to double else if one operand is float convert other operand to float else if both operands are unsigned convert lower rank operand to type of upper rank else if both operands are signed convert lower rank operand to type of upper rank else if unsigned operand has >= rank of signed convert signed operand to type of unsigned else if signed operand cannot represent all values of the unsigned operand convert both to unsigned type of signed operand
3) When converting to a wider type with the same "signedness," the value is preserved.
4) When converting from a signed integer type with negative value to an unsigned integer type, use the unsigned value of the sign-extended two's complement representation of the negativevalue (the words in the standard are different, but the effect is the same). E.g., 8-bit signed -1 to 16-bit unsigned short is 0xFF -> 0xFFFF -> 65535. E.g.2,
16-bit signed value 767 to 8-bit unsigned char is 0x2FF -> 0xFF -> 255
5) If converting to a signed integer type that can't represent the value, the result is undefined.
For your specific examples, the results depend on the types. Assuming a minimum system (8-bit char, 16-bit short/int, 32-bit long):
convert int to long, perform division
type of literal 8000000 is long convert int to long, perform division
convert int to long, perform division, convert result to int
convert int to unsigned char.
One possible surprise is rule 2. Consider:
unsigned char x = 128, y = 32; int z; z = x*y;
should result in z being assigned the value 4096 rather than 0.
HTH,
-=Dave
Change is inevitable, progress is not.
S
Spehro Pefhany
Look up "integer promotions" and "integer conversion rank".
Best regards, Spehro Pefhany
"it's the network..." "The Journey is the reward"
speff@interlog.com Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog Info for designers: http://www.speff.com
P
Paul Burke
It's best not to depend on the promotion rules being implemented fully, and create a temporary variable of the biggest type and work on that. Sub optimal but works.
Same with precedence. A few extra characters won't cost the erath.
Paul Burke
K
kyle york
Just when I thought I understood C -- from where does this come? I don't see it in the standard.
Kyle A. York
Sr. Subordinate Grunt
DSBU
D
Dave Hansen
I've been writing C code for over 20 years, and it can still surprise me every now and again. Such as the time I found out that sizeof(++x) will _not_ increment x (but, IIUC, sizeof(int[++x]) _will_). I guess one reason I found that out so late is that I never tried to code like that. But I digress...
Start with 6.3.1.8 (The Usual Arithmetic Conversions), which eventually gets down to the "integer promotions," which are themselves described in 6.3.1.1.
HTH, -=Dave
Change is inevitable, progress is not.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.