Type Casting

Widening conversions happen automatically, narrowing needs an explicit cast that chops rather than rounds: the reason BookBridge's issue rate printed 0 and how to fix it.

10 min read · 10 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


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?

  1. 7
  2. 8
  3. 7.9
  4. 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.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Introduction to Java

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Type Casting · Java Programming Language · Gri-Learn