Welcome to the World of Limits and Transformations!
In our previous chapters, we learned how to store data in variables like int and double. But what happens if we try to put a giant number into a small variable? Or what if we need to turn a decimal into a whole number? This chapter covers Range (the limits of what a variable can hold) and Casting (the way we change data from one type to another). Don't worry if this seems a bit "mathy" at first—we'll break it down step-by-step!
The Boundaries of Integers: Range
Think of a variable like a storage container. A container has a specific size; if you try to put more than it can hold, you run into trouble. In Java, the int data type has a specific range of values it can store.
Integer.MIN_VALUE and Integer.MAX_VALUE
Java provides two special "constants" that tell us exactly what these limits are. You will need to recognize these for the AP exam:
- Integer.MAX_VALUE: The largest possible value an int can hold. It is exactly \(2,147,483,647\) (about \(2\) billion).
- Integer.MIN_VALUE: The smallest possible value an int can hold. It is exactly \(-2,147,483,648\).
Did you know? These numbers come from the way computers use binary (bits) to store information. An int uses \(32\) bits. One bit is used for the positive/negative sign, leaving \(31\) bits for the number itself. That is why the limit is \(2^{31} - 1\).
What happens if you go over the limit?
If you add \(1\) to Integer.MAX_VALUE, the computer doesn't give an error! Instead, it "wraps around" to the Integer.MIN_VALUE. This is called integer overflow. It’s like an old car odometer that hits \(999,999\) miles and flips back to \(000,000\).
Key Takeaway: Always remember that an int is limited to roughly \(\pm 2\) billion. If your calculation might exceed that, you have to be careful!
Casting: Changing Data Types
Casting is a way to tell Java to treat a value of one type as if it were another type. In this unit, we specifically focus on casting between int and double.
1. Widening (Implicit Casting)
When you put an int into a double variable, Java does the work for you automatically. This is because a double can hold everything an int can, plus decimals. It is "wider."
Example:
double \(myVote = 5;\)
Java will store this as \(5.0\). No extra code is needed!
2. Narrowing (Explicit Casting)
This is where it gets interesting. If you try to put a double (like \(7.99\)) into an int variable, Java will get worried that you are going to lose data and will throw an error. To fix this, you must explicitly cast the value using parentheses.
The Syntax: \((type) expression\)
Example:
double \(price = 9.99;\)
int \(dollars = (int) price;\)
In this case, \(dollars\) will be \(9\).
Important! When you cast a double to an int, Java does not round to the nearest whole number. It truncates the decimal. This means it simply "chops off" everything after the decimal point. \(0.99\) becomes \(0\), and \(9.99\) becomes \(9\).
Casting in Expressions
Casting is very useful when dealing with division. Remember from our "Expressions" chapter that integer division (like \(1 / 2\)) results in \(0\) because Java drops the remainder. Casting can help us get the decimal answer we want.
Scenario A: \(double \text{ result } = 1 / 2;\)
Result is \(0.0\). (Java does the integer division first, gets \(0\), then turns it into a double).
Scenario B: \(double \text{ result } = (double) 1 / 2;\)
Result is \(0.5\). (Java turns the \(1\) into \(1.0\) first. Since one number is a double, it performs double division).
Common Mistake to Avoid:
\(double \text{ result } = (double) (1 / 2);\)
This will still result in \(0.0\)! Why? Because the parentheses around \((1 / 2)\) tell Java to do the integer division first. By the time the cast happens, the decimal is already gone.
Quick Review: Rounding with Casting
Since casting to an int always chops off the decimal, how do we round a positive double to the nearest int? We use a simple trick: add \(0.5\) before casting!
- To round \(x\): \(int \text{ rounded } = (int) (x + 0.5);\)
How it works:
If \(x = 3.2\), then \(3.2 + 0.5 = 3.7\). Casting \(3.7\) to int gives \(3\). (Correct!)
If \(x = 3.8\), then \(3.8 + 0.5 = 4.3\). Casting \(4.3\) to int gives \(4\). (Correct!)
Chapter Summary
- Integer.MAX_VALUE is the ceiling (\(2,147,483,647\)); Integer.MIN_VALUE is the floor (\(-2,147,483,648\)).
- Casting is temporary type conversion using the \((type)\) syntax.
- Casting a double to an int truncates (chops off) the decimal; it does not round.
- To get decimal results from division, cast at least one of the numbers to a double before the division happens.
Don't worry if this seems tricky at first! The more you practice tracing code segments with division and casting, the more natural it will feel. Just remember: the cast operator has high precedence, so it usually happens before the math!