C math & variable types

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

Reply to
Scott Kelley
Loading thread data ...

Isn't that what casting is for??

ian

Reply to
Ian Bell

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.
Reply to
Dave Hansen

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
Reply to
Spehro Pefhany

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

Reply to
Paul Burke

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
Reply to
kyle york

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.
Reply to
Dave Hansen

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.