Theory
The report that said 0%
End of the month, BookBridge prints its proudest number: how much of the library got used.
int issued = 47, total = 60;
System.out.println(issued / total * 100);
Output: 0. The librarian is not impressed. 47 of 60 books went out, that is clearly more than three quarters, and your report claims zero.
Nothing is broken. Java did exactly what the types told it to do, and this lesson is about learning to tell it otherwise.
Theory
Pouring between vessels
Pour a small cup into a big bucket: nothing spills, no permission needed. That is widening: a small type flowing into a bigger one, automatic and safe.
Pour a bucket into a cup: something may spill, so Java refuses unless you explicitly say "I accept the spillage". That is narrowing, and the explicit cast (int) is you signing the waiver.
Theory
Widening and narrowing, formally
Widening (implicit) conversion: Java automatically converts a smaller type to a larger one, with no data loss:
byte → short → int → long → float → double (char joins the ladder at int)
So long isbn = 42; and double price = 350; just work.
Narrowing (explicit) conversion: going down the ladder risks losing data, so it compiles only with a cast operator: int rupees = (int) 350.75; stores 350. The cast is a promise that you accept whatever gets lost.
Practical
Casts in action (predict each print)
public class Casting {
public static void main(String[] args) {
int issued = 47, total = 60;
System.out.println(issued / total * 100); // 0 (int division first)
System.out.println((double) issued / total * 100); // 78.33... (fixed)
double price = 350.75;
int rupees = (int) price; // narrowing: needs the cast
System.out.println(rupees); // 350 (chopped, not rounded)
long big = issued; // widening: automatic
char section = 'C';
int code = section; // char widens to int: 67
System.out.println(code);
}
}
Theory
Why the report said 0
Java evaluates issued / total * 100 left to right, using the operands' types at each step.
issued / total is int divided by int, and integer division keeps only the whole part: 47 / 60 = 0. Then 0 * 100 = 0.
The fix casts ONE operand before the division: (double) issued / total makes it 47.0 / 60 = 0.7833..., and * 100 gives 78.33. Casting the whole result instead, (double)(issued / total), is the classic wrong fix: the damage already happened inside the brackets.
Quiz
What does System.out.println((int) 7.9); print?
- 7
- 8
- 7.9
- Compile error: a double cannot become an int
Show the answer
7
A narrowing cast truncates: it chops off the fractional part and keeps 7. It never rounds, so 8 is the trap for students who assume mathematical rounding. 7.9 would mean the cast did nothing. And option D has it backwards: double to int WITH an explicit cast is exactly what the cast operator is for; it is the version WITHOUT the cast that refuses to compile.
Think first
The byte that went negative
byte b = (byte) 130; System.out.println(b); A byte holds -128 to 127, and 130 does not fit. Before tapping: what prints?
Show the answer
-126. A byte keeps only the lowest 8 bits of the value, and losing the higher bits makes the number wrap around: 130 is 2 steps past 127, the maximum, so it lands 2 steps into the negative end: 130 - 256 = -126. You do not need bit-level working in most exams; remembering out-of-range casts wrap around to strange values is the point: a cast forces the fit, it does not check it.
Watch out
The 3 casting traps
Casting too late: (double)(47 / 60) is 0.0; the int division already destroyed the fraction. Cast an operand, not the result.
Expecting rounding: (int) 7.9 is 7. Casts chop.
Assuming C's tolerance: in C, int x = 3.5; quietly compiles. Java calls it a compile error (possible lossy conversion) and demands the cast. Java never narrows silently; that strictness is the "robust" property from the first lesson doing its job.
Theory
Where casting returns
This is the same idea BCA104 taught for C, with Java enforcing it more strictly. Keep the vocabulary sharp: widening is implicit, narrowing is explicit. The word cast itself returns with a bigger role in Unit 2: once BookBridge has a Person parent class with Member and Librarian children, you will cast object references up and down that family tree, and the up-is-free, down-needs-care rule will feel exactly like this lesson.
Summary
Key takeaways
- Widening (small to large: byte, short, int, long, float, double; char joins at int) is automatic and lossless.
- Narrowing (large to small) needs an explicit cast: int rupees = (int) 350.75;
- Casts truncate, never round: (int) 7.9 is 7.
- int / int is integer division; cast one operand, not the bracketed result: (double) issued / total.
- Out-of-range casts wrap: (byte) 130 is -126.
- Java refuses implicit narrowing at compile time; C tolerated it silently.
- Memory hook: small to big flows free, big to small you sign the waiver.