From the free course AP Computer Science A on Lykke

1.5 Casting and Range of Variables

Key concepts: Casting double values to int in Java · Generating random integers with Math.random() · Converting a random decimal to a bounded integer range · Inclusive integer ranges · Uniform random-number generation · Calculating 5% and 95% probabilities · Using conditional logic for probabilistic outcomes · Guarding against negative variable values

Java’s Math.random() produces a decimal, but many programs need a whole-number outcome—such as a die roll, a temperature category, or a bird’s daily food consumption.

1.5 Casting and Range of Variables

Java’s Math.random() produces a decimal, but many programs need a whole-number outcome—such as a die roll, a temperature category, or a bird’s daily food consumption. Casting converts a value from one data type to another; when a double is cast to an int, Java truncates the decimal portion rather than rounding it.

CED traceability: Learning Objective 1.5.A; Essential Knowledge 1.5.A.1, 1.5.A.2. This topic develops Design Code, Develop Code, and Analyze Code, especially reasoning about ranges, conversions, and probabilistic branches.

Casting a double to an int

Suppose amount stores the value $27.9$:

double amount = 27.9;
int wholeAmount = (int) amount;

After the cast, wholeAmount is $27$. The cast removes everything after the decimal point; it does not choose the nearest integer. Thus, (int) 4.99 becomes $4$, and (int) -4.99 becomes $-4$.

The parentheses matter because Java’s cast operator applies only to the expression immediately following it. Compare these expressions:

(int)(Math.random() * 100)
(int)Math.random() * 100

The first expression scales the random decimal to a value from $0.0$ up to, but not including, $100.0$, then truncates it. The second casts Math.random() first; since every value is between $0.0$ and $1.0$, the cast becomes $0$, and the multiplication produces $0$ every time.

Named misconception — “Casting rounds.” Casting a double to an int truncates toward zero. If a program needs rounding, a different operation is required; casting alone never rounds $27.9$ to $28$.

Turning random decimals into integer ranges

Math.random() returns a double in the interval $[0.0, 1.0)`: $0.0$ is possible, but $1.0$ is not. Multiplying by a positive integer changes the interval’s upper boundary without including it.

Expression Possible integer results after casting
(int)(Math.random() * 100) $0$ through $99$
(int)(Math.random() * 101) $0$ through $100$

The multiplier determines how many consecutive integer outcomes are available. A multiplier of $100$ creates $100$ possibilities—$0$ through $99$—while a multiplier of $101$ creates $101$ possibilities—$0$ through $100$.

Inclusive ranges: the upper-bound formula

To generate a uniform random integer in an inclusive range from low through high, use:

$$ (\text{int})(\text{Math.random()} \times (\text{high} - \text{low} + 1)) + \text{low} $$

The expression contains three deliberate steps:

  1. high - low + 1 counts the number of possible integers.
  2. Multiplication creates a decimal from $0.0$ up to that count, excluding the count.
  3. Casting produces an integer offset, and the lower bound shifts the result.

For the inclusive range $[10,50]$, there are $50-10+1=41$ possible values:

int foodEaten = (int)(Math.random() * 41) + 10;

The cast produces $0$ through $40$; adding 10 shifts those outcomes to $10$ through $50$. Each integer receives an equal-sized slice of the random interval, so the generation is uniform.

Range check: When the desired range is 10–50, multiplying by 50 incorrectly generates 0–49; adding 10 to a 0–50 result incorrectly generates 10–60.

Modeling a 5% event

A random decimal can also choose between events. Because Math.random() is uniformly distributed over $[0.0,1.0)$, the test below is true approximately $5%$ of the time:

double chance = Math.random();

if (chance < 0.05)
{
    currentFood = 0;
}
else
{
    currentFood = (int)(Math.random() * 41) + 10;
}

The interval $[0.0,0.05)$ occupies $5%$ of the total interval. Its complement occupies $95%$, so the else branch occurs approximately $95%$ of the time. The random value used for the probability decision should remain a double; casting it before the comparison would turn it into $0$ almost every time.

The bird-food guard

In a daily bird-food simulation, the birds either consume all remaining food in the $5%$ case or eat a random amount from $10$ through $50$ grams in the remaining $95%$ of cases. Subtracting without protection can make currentFood negative, which violates the simulation’s meaning: food cannot drop below zero.

if (Math.random() < 0.05)
{
    currentFood = 0;
}
else
{
    int eaten = (int)(Math.random() * 41) + 10;
    currentFood -= eaten;

    if (currentFood < 0)
    {
        currentFood = 0;
    }
}

The guard corrects the state after subtraction. It does not change the random range; it ensures that the stored food amount remains physically valid.

Retrieval check: What are the possible results of (int)(Math.random() * 6) + 2? Why does (int)(Math.random() * 50) + 10 fail to generate every value from $10$ through $50$?

Answer: The first expression produces $2$ through $7$: the cast gives $0$ through $5$, then the offset shifts the range. The second produces $10$ through $59$, because multiplying by $50$ creates $50$ possible offsets, not the $41$ offsets required for $10$ through $50$.

1.5 Casting and Range of Variables - AP Computer Science A - image 1
1.5 Casting and Range of Variables - AP Computer Science A - image 1
1.5 Casting and Range of Variables - AP Computer Science A - diagram 1
1.5 Casting and Range of Variables - AP Computer Science A - diagram 1

Source Materials

The whole course on Lykke · Browse all public course wikis