AP COMPUTER SCIENCE A • USING OBJECTS AND METHODS

Casting and Range of Variables

Understanding how Java converts between primitive types and the numeric limits that govern each data type.

Historical Context & Motivation

Programming languages have grappled with the problem of representing numbers in finite memory since the earliest days of computing. When engineers built the first electronic computers in the 1940s, they had to decide how many bits to allocate for each number — a constraint that immediately imposed limits on the range of values a machine could handle. As languages evolved from raw machine code to higher-level abstractions, the need for type casting — converting a value from one data type to another — became a central design problem. Without casting, programmers would be trapped within a single numeric representation, unable to mix integers with floating-point values or reconcile data from different sources.

1957
FORTRAN Introduces Implicit Conversion
IBM's FORTRAN compiler automatically converts integers to floating-point values in mixed expressions, establishing the concept of implicit type promotion that Java would later adopt.
1972
C Language and Explicit Casts
Dennis Ritchie's C language formalizes the cast operator syntax — (type)expression — giving programmers explicit control over type conversion, a notation Java would inherit almost verbatim.
1985
IEEE 754 Standardizes Floating-Point
The IEEE 754 standard defines how floating-point numbers are stored in 32-bit (float) and 64-bit (double) formats, establishing the precision and range conventions that all modern languages, including Java, rely upon.
1995
Java's Type-Safe Design
James Gosling and the Java team at Sun Microsystems release Java 1.0 with strictly defined primitive types, fixed sizes across all platforms, and clear rules for widening and narrowing conversions — eliminating the platform-dependent bugs that plagued C and C++.

Java's designers deliberately chose to fix the size of every primitive type regardless of the underlying hardware. An int is always 32 bits whether the program runs on a phone or a supercomputer. This portability guarantee means that every Java programmer must understand two intertwined questions: what range of values each type can represent, and what happens when you need to convert between types — safely or otherwise.

Core Principles & Definitions

Before exploring the mechanics of casting, you need a firm grasp of the foundational ideas that govern how Java handles primitive data types. The AP Computer Science A exam focuses primarily on int and double, though understanding the broader type hierarchy helps you reason about why certain conversions are safe while others are not.

1

Primitive Types & Bit Width

Java's numeric primitives include byte (8 bits), short (16 bits), int (32 bits), long (64 bits), float (32 bits), and double (64 bits). The AP exam concentrates on int and double. Each type's bit width determines both its range and its precision.
2

Widening (Implicit) Casting

When you assign a smaller type to a larger type (e.g., int → double), Java performs an automatic widening conversion. No data is lost, so no explicit cast is required. This is also called implicit casting.
3

Narrowing (Explicit) Casting

Converting a larger type to a smaller one (e.g., double → int) requires an explicit cast operator because information — specifically the fractional part — may be lost. Java truncates toward zero rather than rounding.
4

Overflow and Underflow

When a computation exceeds the maximum (or minimum) value of a type, the value wraps around silently — Java does not throw an exception. This phenomenon is called integer overflow (or underflow), and it can produce wildly incorrect results.
5

Precision vs. Range

A double has enormous range (≈ ±1.8 × 10³⁰⁸) but limited precision (about 15–17 significant decimal digits). An int has a smaller range (≈ ±2.1 × 10⁹) but exact precision for every value within that range. Casting between them trades one property for the other.
KEY TAKEAWAY
Think of casting like pouring liquid between containers. Pouring from a small cup into a large bucket (widening) is effortless and spills nothing. Pouring from a large bucket into a small cup (narrowing) works, but whatever overflows the cup is lost forever. Java forces you to say "I know some liquid might spill" by requiring the explicit cast operator — the compiler will not let you lose data silently.

Visual Explanation — The Type Hierarchy

The diagram above shows Java's widening conversion hierarchy. Each arrow represents an implicit (automatic) cast. The two types highlighted with dashed borders — int and double — are the focus of the AP Computer Science A exam. Notice that int → float (the dashed diagonal arrow) is a widening conversion but may lose precision because float has only ~7 significant digits.

The key insight from this diagram is that widening conversions always move in the direction of greater range (or greater precision for floating-point types). Java performs these automatically whenever you assign a smaller type to a larger type, pass an int argument to a method expecting a double parameter, or use mixed types in an arithmetic expression. Going in the reverse direction — for instance, from double to int — requires an explicit narrowing cast and risks losing the fractional portion of the value.

How Casting Works in Java

Widening Conversion: int → double

When Java widens an int to a double, it converts the 32-bit two's complement integer representation into a 64-bit IEEE 754 double-precision floating-point representation. Because a double has 52 mantissa bits (plus one implicit leading bit, giving 53 bits of effective precision), it can represent every int value exactly. This is why the widening conversion from int to double is lossless.

INT RANGE
−2³¹ ≤ int ≤ 2³¹ − 1
Evaluates to −2,147,483,648 to 2,147,483,647. These values are available as Integer.MIN_VALUE and Integer.MAX_VALUE.

Narrowing Conversion: double → int

Java's narrowing cast from double to int performs truncation toward zero: the fractional part is simply discarded. This is not rounding — (int) 9.99 yields 9, and (int) −3.7 yields −3. The compiler refuses to compile a narrowing conversion without the explicit cast operator because the programmer must acknowledge the potential loss of information.

NARROWING CAST SYNTAX
int result = (int) doubleValue;
The cast operator (int) precedes the expression. Truncation removes all digits after the decimal point.

Casting in Arithmetic Expressions

One of the most common AP exam scenarios involves integer division. When both operands of the / operator are int values, Java performs integer division, which truncates the quotient. To obtain a floating-point result, at least one operand must be cast to double before the division occurs. For example, (double) 7 / 2 evaluates to 3.5 because the cast converts 7 to 7.0 first, which then promotes the entire expression to double arithmetic. Contrast this with (double)(7 / 2), which performs integer division first (yielding 3) and then converts 3 to 3.0 — a very different result.

INTEGER DIVISION
7 / 2 → 3 (integer division, fractional part discarded)
But (double) 7 / 27.0 / 23.5 because casting occurs before division.

Ranges, Overflow, and Precision Loss

Understanding the exact numeric ranges of Java's primitive types is essential for predicting when overflow occurs and why certain casts lose information. The table below summarizes the types most relevant to the AP Computer Science A exam.

Java Numeric Primitive Types – Ranges
TypeBitsMinimum ValueMaximum ValueNotes
int32−2,147,483,6482,147,483,647≈ ±2.1 × 10⁹. Exact for all values.
double64≈ −1.8 × 10³⁰⁸≈ 1.8 × 10³⁰⁸~15–17 significant digits. Not exact.
byte8−128127Rarely on AP exam.
long64≈ −9.2 × 10¹⁸≈ 9.2 × 10¹⁸Rarely on AP exam.
This diagram illustrates integer overflow using a simplified 4-bit analogy. When the maximum positive value (0111 in binary) has 1 added to it, the result (1000) is interpreted as the most negative value because the leading bit becomes the sign bit. The same principle applies to Java's 32-bit int type, where Integer.MAX_VALUE + 1 silently wraps to Integer.MIN_VALUE.
AP Exam Alert
The AP Computer Science A exam will not ask you to convert between binary and decimal, but you are expected to recognize that overflow wraps around silently. A common multiple-choice trap is code that computes a sum exceeding Integer.MAX_VALUE and produces an unexpected negative result.

Worked Example — Casting in Practice

Consider the following code segment. Trace through each line, predicting the value stored and the type of the result.

Tracing Casts and Integer Division
1
Step 1 — Analyze integer divisionGiven int a = 7; int b = 2;, evaluate int c = a / b;. Since both operands are int, Java performs integer division: 7 / 2 truncates to 3.
c = 3 (int)
2
Step 2 — Widening assignmentEvaluate double d = a / b;. The division a / b is still integer division (both operands are int), producing 3. Then the int result 3 is implicitly widened to 3.0 for assignment to the double variable.
d = 3.0 (double) — NOT 3.5!
3
Step 3 — Pre-division castEvaluate double e = (double) a / b;. The cast (double) applies to a first (due to precedence), converting 7 to 7.0. Now the expression is 7.0 / 2. Since one operand is a double, Java promotes b to 2.0 and performs floating-point division.
e = 3.5 (double)
4
Step 4 — Post-division cast (common trap)Evaluate double f = (double)(a / b);. The parentheses force integer division first: a / b = 3. Then the cast converts 3 to 3.0. The fractional information was already lost.
f = 3.0 (double) — truncation already happened!
5
Step 5 — Narrowing cast on a negative valueEvaluate int g = (int) −9.8;. Java truncates toward zero — the fractional part −0.8 is discarded. The result is −9, not −10. This distinction between truncation and rounding (Math.round) is a frequent exam question.
g = −9 (int) — truncated toward zero
KEY TAKEAWAY
The order of operations matters critically when casting. Casting one operand before a division ("pre-cast") changes the arithmetic to floating-point. Casting the result after a division ("post-cast") merely converts an already-truncated integer to a double. On the exam, trace these step-by-step, resolving the innermost expression first.

Common Pitfalls and Comparisons

Many bugs involving casting and variable ranges appear simple in isolation but become tricky in the context of compound expressions, loops, and method calls. The table below contrasts correct and incorrect approaches for common scenarios.

Common Casting Pitfalls
ScenarioIncorrect CodeCorrect CodeWhy
Compute average of two intsint avg = (a + b) / 2;double avg = (double)(a + b) / 2;Integer division truncates the quotient. Cast the sum before dividing.
Percentage calculationint pct = score / total * 100;double pct = (double) score / total * 100;score / total yields 0 when score < total. Cast first.
Sum large intsint sum = 2000000000 + 2000000000;long sum = 2000000000L + 2000000000L;The sum exceeds Integer.MAX_VALUE. Use long literals.
Rounding a doubleint r = (int) 4.7;int r = (int)(4.7 + 0.5);Cast truncates; add 0.5 first for rounding (or use Math.round).
KEY TAKEAWAY
Most casting bugs on the AP exam exploit the difference between casting before versus after an operation. Think of the cast operator as a gatekeeper standing at a specific point in the expression. Data that passes the gatekeeper changes type, but everything that happened upstream remains in the original type. Position the gatekeeper (the cast) as early as possible if you need a floating-point result.

Connection to Advanced Topics

Casting between primitive types is the foundation for several advanced topics you will encounter both later in the AP course and in college-level computer science. Understanding how Java resolves types at compile time versus run time prepares you for the broader concept of polymorphism and reference casting, where objects — not just numbers — are converted between types in an inheritance hierarchy.

Primitive vs. Reference Casting
This Lesson (Primitive Casting)Advanced Topic (Reference Casting)
Widening: int → double (implicit, safe)Upcasting: subclass → superclass reference (implicit, safe)
Narrowing: double → int (explicit, may lose data)Downcasting: superclass → subclass reference (explicit, may throw ClassCastException)
Overflow wraps silently for intsInvalid downcast throws a runtime exception
Cast operator: (int), (double)Cast operator: (SubclassName)

Additionally, the concept of autoboxing — where Java automatically converts between primitive types (like int) and their corresponding wrapper classes (like Integer) — builds directly on the casting principles covered here. When you work with ArrayList<Integer> later in the course, Java performs implicit boxing and unboxing conversions that mirror the widening and narrowing logic you have learned. Understanding casting now gives you a mental model that scales to these more complex scenarios.

🔮 Looking Ahead
On the AP exam, FRQ questions occasionally require casting to compute a correct average or percentage inside a loop. Keep this lesson's principles in mind whenever you see division with int variables — it is one of the most commonly tested patterns.

Practice Problems

1
Which of the following best describes what happens when a double value is cast to an int in Java?
2
What is the output of the following code? int x = 11; int y = 4; double result = (double) x / y; System.out.println(result);
3
Consider the following code segment: int a = Integer.MAX_VALUE; int b = a + 1; System.out.println(b); What is printed?
PROBLEM 4APPLIED
A teacher stores each student's total points earned as an int and the total points possible as an int. Write a Java expression that computes the percentage grade as a double (for example, 85.5 for 85.5%). Then explain what would happen if you forgot to cast and simply wrote earned / possible * 100.
PROBLEM 5CRITICAL THINKING
Consider the following method: public static int computeAverage(int[] arr) { int sum = 0; for (int val : arr) { sum += val; } return sum / arr.length; } (a) Identify TWO distinct problems related to casting and range of variables in this method. (b) For each problem, provide a specific input (array contents) that would trigger incorrect behavior. (c) Rewrite the method to fix both problems, returning a double that correctly represents the average.

Lesson Summary

Java's primitive types each have a fixed bit width that determines their range of representable values. The int type stores 32-bit integers from −2,147,483,648 to 2,147,483,647, while the double type stores 64-bit floating-point values with enormous range but limited precision (~15 significant digits). Widening conversions (int → double) happen automatically and are lossless, while narrowing conversions (double → int) require an explicit cast and truncate toward zero.

The most critical AP exam pattern is integer division: when both operands are ints, the quotient is truncated. To obtain a floating-point result, cast at least one operand to double before the division. Remember that integer overflow wraps around silently — Java does not throw an exception — so always consider whether intermediate calculations could exceed Integer.MAX_VALUE or fall below Integer.MIN_VALUE. These principles form the foundation for understanding reference casting and polymorphism later in the course.

Varsity Tutors • AP Computer Science A • Casting and Range of Variables