Step 1 of 5 · Reading · ~3 min
Learn
Getting Started
Numbers and printf
By the end of this lesson you can predict what C arithmetic produces before you run it, and print integers and decimals in exactly the format a grader expects. Two rules do most of the work: the operands decide the arithmetic, and each printf specifier is a promise about the type of the next argument.
Integer division truncates
printf("%d\n", 7 / 2); /* 3 - int / int stays int, fraction dropped */
printf("%d\n", 7 % 2); /* 1 - remainder */
printf("%d\n", 99 / 100); /* 0 - the "percentage is always zero" classic */
printf("%f\n", 7.0 / 2); /* 3.500000 - one double makes it a double division */
The type of a division is decided by its operands, not by where the result goes. double d = 7 / 2; stores 3.0: the division finished in integer land before the assignment happened. To keep the fraction, cast one operand first. A cast is a type name in parentheses in front of a value, and it converts that value:
int points = 17;
int games = 4;
double wrong = points / games; /* 4.00 - truncated, then widened */
double avg = (double)points / games; /* 4.25 - double / int is a double division */
The cast must sit on an operand. (double)(points / games) is still 4.00, because the inner parentheses make the integer division run first.
Integer overflow
An int holds at most 2,147,483,647. Multiply two large ints and the result does not fit; for signed types this is undefined behaviour, and on this grader you typically see a wrapped, often negative, number. Widening the result variable is not enough, for the same reason as with division:
int rows = 60000;
int per_row = 50000;
long long bad = rows * per_row; /* int * int overflows first */
long long good = (long long)rows * per_row; /* 3000000000 */
long long is 64-bit (up to about 9.2 * 10^18). Cast one operand before the multiply, and print the result with %lld.
printf: the specifier contract
| Specifier | Argument type | Example | Prints |
|---|---|---|---|
%d | int | printf("%d", 42) | 42 |
%lld | long long | printf("%lld", 3000000000LL) | 3000000000 |
%f | double | printf("%f", 4.25) | 4.250000 |
%.2f | double | printf("%.2f", 4.256) | 4.26 |
%.1f | double | printf("%.1f", 0.04) | 0.0 |
%f alone always prints six decimals, so a grader expecting 4.25 rejects 4.250000. %.2f prints exactly two and rounds (4.256 becomes 4.26, not 4.25), so you never round by hand.
Mismatch a specifier and its argument and you get undefined behaviour, not an error: printf("%f\n", 15) prints 0.000000 here, and printf("%d\n", 4.25) prints an unrelated integer. gcc -Wall warns about both at compile time, so read the warnings.
Common mistakes
- Dividing two ints and hoping for a fraction.
(double)(a / b)ordouble r = a / b;gives3.00where3.50was wanted, and0.00whenever the top number is smaller than the bottom one. - Multiplying two ints into a
long long. The product overflows before the assignment, so 46341 * 46341 prints a negative number instead of2147488281. - Wrong specifier.
%dfor along longor%ffor an int prints garbage;%ffor a decimal prints six places instead of two. - Extra text.
Area: 15fails where15passes; the comparison is on every character.
Your exercise
Given a rectangle's width and height, print its area and its width-to-height ratio. The starter reads both numbers as int; you write the arithmetic and the two printf calls. The mistake the hidden tests are waiting for is an integer division or an integer multiply that happens before any conversion.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…