📦 Variables & Types · Beginner

Narrowing casts in Java

Explicit (int) casts, truncation of decimals and bits lost on overflow.

🧩 The mystery(byte) 300 is 44. (int) 3e9 is 2147483647. (int) -2.7 is -2. Three casts, three completely different rules. Let's decode them.

A cast says: I take responsibility

Converting to a narrower type needs an explicit cast: the target type in parentheses. Without it you get a compile error, even when the value would fit. The compiler checks types, not values.

int n = 10;
short s = n;          // error
short t = (short) n;  // ok: 10

Decimals → integers: chop

Casting a double or float to an integer type drops the fractional part, truncating toward zero. It does not round. Want rounding? Use Math.round.

(int) 9.99         // 9
(int) -2.7         // -2, toward zero
Math.round(9.99)   // 10
Math.floor(-2.7)   // -3.0
🔮 Predict it

Your turn

What does this print?

System.out.println((int) 7.9);
System.out.println((int) -7.9);
  1. 7 -7
  2. 8 -8
  3. 7 -8
Show the answer

Truncation always goes toward zero: 7.9 → 7 and -7.9 → -7. Nothing is rounded.

Integers → smaller integers: keep low bits

int → byte keeps only the lowest 8 bits and throws the rest away. 300 is 1_0010_1100 in binary; keep 0010_1100 and you get 44. The value can change completely, even its sign. It isn't clamped to 127.

🔮 Predict it

Your turn

What does this print?

int big = 200;
byte b = (byte) big;
System.out.println(b);
  1. 200
  2. 127
  3. -56
Show the answer

200 is 1100_1000. As a byte, the top bit is the sign bit, so those 8 bits mean -56. Integer narrowing keeps the low bits, never clamps.

⚠️ The trap

Too-big decimals clamp instead

Different rule for floating point: casting a double that's too large for an int clamps it to Integer.MAX_VALUE (or MIN_VALUE). Only integer-to-integer narrowing wraps around.

(int) 3_000_000_000.0   // 2147483647
(int) -1e10             // -2147483648
💼 In the real world

In real projects

In 1996 the Ariane 5 rocket self-destructed less than a minute after launch: its software converted a 64-bit floating-point value into a 16-bit integer that couldn't hold it. Every narrowing cast deserves a "can this overflow?" check.

Key takeaways

  1. Narrowing needs a cast: int x = (int) 3.9;
  2. double → int truncates toward zero, it doesn't round
  3. int → byte keeps only the lowest 8 bits
  4. Too-large doubles clamp to Integer.MAX_VALUE
🤯 Did you know?

In 1982 the Vancouver Stock Exchange index started at 1,000. Thousands of updates truncated instead of rounding, and by late 1983 it read about 525 when the correct value was about 1,099.

Practice questions

What does this print?

System.out.println((int) -2.7);
  1. -3
  2. -2.7
  3. 2
  4. -2
Check your answer

-2. The cast truncates toward zero, so −2.7 becomes −2, not −3. Math.floor would give −3.0.

What does this print?

int n = 10;
short s = n;
System.out.println(s);
  1. 10
  2. Compile error
  3. 0
  4. Throws ClassCastException
Check your answer

Compile error. int → short is narrowing, so the compiler requires an explicit (short) cast even though 10 would fit.

Next: why won't byte + byte fit back into a byte? Java quietly promotes your numbers behind your back.