Lesson 2: Variables, Data Types, and CastingAP
🎧 Listen to this lesson
Unit 1 of the CED (topics 1.2–1.5) is about how Java represents values: variables, the primitive types int, double and boolean, arithmetic expressions, assignment, and casting. These ideas look elementary, but expression-tracing questions built from them appear on every AP exam, because a single misunderstanding — integer division, say — silently corrupts every later topic. Master the exact rules now.
Variables and the primitive types
A variable is a named storage location with a declared type that never changes. Declaration and initialisation are often combined: int score = 95;. The three primitive types in the AP subset are:
| Type | Holds | Examples | Default arithmetic behaviour | ||
|---|---|---|---|---|---|
int | whole numbers, roughly ±2.1 billion | 42, -7, 0 | division truncates toward zero | ||
double | decimal numbers | 3.5, -0.25, 2.0 | division keeps the fractional part | ||
boolean | truth values | true, false | used with &&, ` | , !` |
A final variable is a constant: final double TAX_RATE = 0.07; — assign it once; the compiler rejects any later assignment. Naming matters for readability on FRQs: graders follow your code more easily when totalCost is not called x.
Arithmetic and the great division trap
The operators are +, -, *, / and % (remainder), with the usual precedence: *, /, % bind tighter than +, -, and parentheses override everything. The single most tested rule in Unit 1:
/ are int, the result is an int — the fractional part is truncated (thrown away), not rounded. 7 / 2 is 3. If either operand is a double, the result is a double: 7 / 2.0 is 3.5.The % operator gives the remainder of integer division: 17 % 5 is 2. Remainders have three exam-standard uses: parity (n % 2 == 0 tests evenness), digit extraction (n % 10 is the last digit of n; n / 10 deletes it), and wrap-around (clock arithmetic, rotating indices). Trace the following carefully:
| Expression | Value | Why |
|---|---|---|
17 / 5 | 3 | int division truncates 3.4 |
17 % 5 | 2 | 17 = 5·3 + 2 |
17.0 / 5 | 3.4 | one double operand → double division |
(double) 17 / 5 | 3.4 | cast applies to 17 first, then double division |
(double) (17 / 5) | 3.0 | division happens first (both int), cast afterwards — the classic trap |
5 + 17 % 5 | 7 | % before + |
-17 % 5 | -2 | sign of the remainder follows the dividend in Java |
Assignment and compound operators
= assigns; it does not compare. Compound forms compress update patterns: x += 4; means x = x + 4;, and similarly -=, *=, /=, %=. The increment operators i++ and i-- add or subtract 1 — as statements they are interchangeable with i += 1. (In the middle of larger expressions, prefix and postfix forms differ; AP code almost always uses them as standalone updates, and you should too.)
int points = 10;
points += 5; // 15
points *= 2; // 30
points %= 7; // 2 (30 = 7*4 + 2)
points++; // 3
Casting and overflow
A cast converts a value to another type: (int) 3.99 is 3 — casting a double to int truncates toward zero, so (int) -3.99 is -3, not -4. Casting is also how you defeat integer division: to average three ints as a decimal, write (double) (a + b + c) / 3 or (a + b + c) / 3.0. Know the constants Integer.MAX_VALUE (2,147,483,647) and Integer.MIN_VALUE: int arithmetic wraps on overflow instead of erroring — Integer.MAX_VALUE + 1 equals Integer.MIN_VALUE. That silent wrap caused real-world bugs (including a famous video-view counter overflow), and the exam tests it directly.
One more concatenation rule, used constantly with output: + with a String operand means concatenation, evaluated strictly left to right. "x" + 2 + 3 is "x23" (the 2 and 3 are glued on one at a time), while 2 + 3 + "x" is "5x" (the numbers add first, because no string appears until the end).
Trace table: following values precisely
Examiners expect you to trace assignments exactly as the JVM executes them — sequentially, using the *current* values:
int a = 8;
int b = 3;
a = a / b; // line 3
b = a + b * 2; // line 4
a = (int) (b / 2.0); // line 5
| After line | a | b | Reasoning |
|---|---|---|---|
| 1–2 | 8 | 3 | initialisation |
| 3 | 2 | 3 | 8 / 3 truncates to 2 |
| 4 | 2 | 8 | uses the new a: 2 + 3 * 2 = 8 |
| 5 | 4 | 8 | 8 / 2.0 = 4.0, cast to int gives 4 |
Real-world design: money is not a double
Professional systems almost never store money in a double, because binary floating-point cannot represent values like 0.10 exactly, and tiny rounding errors accumulate across millions of transactions. Instead they store cents in an int (or a long) and format for display. This is the same reason the exam's casting questions matter: choosing the representation *is* a design decision, and integer division/remainder are how you split a cent total back into dollars and cents (total / 100 and total % 100).
Common mistakes (from examiner reports)
- Casting too late.
(double)(7 / 2)gives3.0— the damage happened inside the parentheses. Cast an operand, not the result. - Assuming
%is "percent".50 % 4is2, the remainder — not 2 or 12.5. - Rounding instead of truncating.
(int) 9.99is9. Students who write 10 lose the point. - String glue order.
"Sum: " + 4 + 5printsSum: 45, notSum: 9. Use parentheses:"Sum: " + (4 + 5). - Reassigning a
final. Any second assignment to a constant is a compile error. - Losing the fraction in averages. An average computed with only int division is wrong whenever the sum is not evenly divisible — the #1 FRQ arithmetic bug in Unit 1-style questions.
(int) (7.8 + 2.9), and how does it differ from (int) 7.8 + (int) 2.9? (11 versus 9 — the cast placement decides when truncation happens.)AP Exam Experience
Question 1. What is the value of the expression (double) (13 / 4) + 13 % 4?
- (A)
4.0 - (B)
4.25 - (C)
6.25 - (D)
7.0 - (E)
3.25
Answer: (A). 13 / 4 is int division → 3; casting gives 3.0; 13 % 4 is 1; 3.0 + 1 is 4.0. (B) is the trap for assuming the cast distributes over the division.
Question 2. Consider the following code segment.
int x = 5;
int y = 2;
x = x + y;
y = x - y;
x = x - y;
System.out.println(x + " " + y);
What is printed?
- (A)
5 2 - (B)
7 5 - (C)
2 5 - (D)
7 2 - (E)
2 7
Answer: (C). Trace it: after x = x + y, x is 7; y = x - y gives 7 - 2 = 5; x = x - y gives 7 - 5 = 2. This is the classic swap-without-a-temp — it works only because each step uses freshly updated values. (B) results from stopping the trace one step early.
Question 3. Consider the following code segment.
int n = 402;
System.out.println(n % 10 + " " + (n / 10) % 10);
What is printed?
- (A)
2 0 - (B)
4 0 - (C)
0 2 - (D)
2 4 - (E)
0 4
Answer: (A). 402 % 10 extracts the last digit, 2. 402 / 10 is 40 (truncation deletes the 2), and 40 % 10 is 0 — the tens digit. Digit-extraction questions are pure /–% teamwork.
Free-Response Question. This question involves methods that process integer scores. (a) Write the static method average3, which takes three int parameters and returns their average as a double. For example, average3(7, 8, 10) should return 8.333... (the value of 25/3 as a decimal), not 8.0. (b) Write the static method lastTwo, which takes a positive int parameter n and returns the value formed by the last two digits of n as an int. For example, lastTwo(2024) returns 24 and lastTwo(7) returns 7.
Scoring guideline (9 points). Part (a) — 5 points:
- +1 Correct method header: returns
double, threeintparameters - +1 Computes the sum of the three parameters
- +1 Avoids integer-division truncation (casts an operand to
double, or divides by3.0) - +1 Divides the total by 3 (the count of values)
- +1 Returns the computed value (no printing instead of returning)
Part (b) — 4 points:
- +1 Correct method header: returns
int, oneintparameter - +1 Uses
%(remainder) to isolate digits - +1 Uses the correct modulus, 100, for two digits
- +1 Returns the result for all positive inputs, including values under 100
Model solution.
public static double average3(int a, int b, int c)
{
return (a + b + c) / 3.0;
}
public static int lastTwo(int n)
{
return n % 100;
}
## Going deeper: the temperature conversion trap
A classic Unit 1 program converts Fahrenheit to Celsius with `celsius = (f - 32) * 5 / 9`. Written with all `int` values, converting 100°F gives `(68) * 5 / 9` = `340 / 9` = `37` — truncated from 37.77..., and defensible if an integer answer is wanted. But the reordered version `celsius = (f - 32) * (5 / 9)` gives `68 * 0` = **0**, because `5 / 9` is integer division and collapses to 0 before the multiplication ever happens. The lesson generalises: in a chain of operations, find the divisions and ask of each one, "are both operands int *at this moment*?" Order of operations decides when the trap springs. A safe habit for conversion and average formulas is to force the issue once, early: multiply by a `double` literal (`5.0 / 9`) or cast the first operand, and let widening carry the rest of the expression.
📊 Interactive
Interactive — hover or explore the chart above.
🎬 Watch & Learn
Free YouTube video lessons on “Variables, Data Types, and Casting” — pick a result below: