Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Data Types  ›  Lesson

Type Conversion

Type Conversion 14 minIn mixed arithmetic C converts both operands to a common, usually wider type before computing, assignment converts the result to the target's type, and a cast forces a conversion where you choose.

Type Conversion

The logger's daily total is 644 tenths from 3 readings, so the average should be about 214.67. The code stores it in a double, yet it prints 214.0. Nothing is broken; C did exactly what its conversion rules say, one step at a time. Learn the steps and this bug becomes impossible to miss.

The rule

Mixed arithmetic climbs to the wider type; assignment squeezes back down.

Before an operator works, both operands are brought to a common type (the usual arithmetic conversions):

  1. Small integer types (char, short, bool) are first promoted to int.
  2. If either operand is floating-point, the other is converted to that floating type (long double beats double beats float).
  3. Otherwise the smaller integer type is converted to the larger one. If a signed and an unsigned type of the same size meet, the signed value becomes unsigned.

Assignment converts the result to the target's type:

  • double to an integer type truncates toward zero: (int)21.9 is 21 and (int)-3.8 is -3. If the value does not fit in the integer type, the behaviour is undefined.
  • A value converted to an unsigned type wraps modulo its range.
  • An out-of-range value converted to a smaller signed type gives an implementation-defined result.

A cast, (type)value, forces a conversion exactly where you put it:

int total = 644;
int count = 3;

double wrong = total / count;           /* int / int = 214, then 214.0 */
double right = (double)total / count;   /* double / int: count climbs too, 214.666... */

The order is the whole point. In wrong, the division finishes as integer division before the assignment converts anything, and the fraction is already gone. Writing (double)(total / count) fails the same way: the parentheses make the integer division happen first, and the cast only converts its result.

The signed/unsigned rule causes a classic trap:

int t = -5;
unsigned int limit = 10;
if (t < limit) { /* never runs: -5 becomes 4294967291 with 32-bit unsigned */ }

-Wextra warns about this with -Wsign-compare.

The shortcut

Before each operator, name the two types. Promote, find the common type, compute, then convert once more at the =.

Evaluating 7 / 2 * 2.0Step 1 of 4
  1. First operator: 7 / 2

    Both are int, so integer division: 3. The half is dropped here.

Drills

Answer fast — trust the rule.

quick drill

What does double r = 7 / 2; store?

quick drill

What is the value of (double)7 / 2?

quick drill

What does int n = (int)-3.8; store?

quick drill

With 32-bit unsigned int, what is the value of -1 < 1u?

quick drill

What does int big = (int)1e20; store on a platform with 32-bit int?

Remember

  • Mixed arithmetic climbs to the wider type; assignment squeezes back down.
  • Shortcut: name the two types before each operator, and cast before the division, not after.
  • Trap: signed meets unsigned and the signed value turns into a huge unsigned one.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainThe average that lost its decimals

The logger has int total = 644; int count = 3; double avg = total / count; and avg comes out as 214.0. Explain why, fix it, and then explain why -5 < 10u is false.