📦 Variables & Types · Beginner

Widening conversions in Java

Automatic safe conversions (int → long → float → double) and precision loss in long → float.

🧩 The mysteryPut a long into a float with no cast and no warning, and the number changes. How can an "automatic, safe" conversion lose data?

Small into big: automatic

Java converts a value to a wider type automatically, no cast needed. This is a widening conversion. Along the chain byte → short → int → long → float → double (and char → int), the value never overflows.

int i = 7;
long l = i;      // int to long
double d = i;    // int to double
int c = 'A';     // char to int: 65
🔮 Predict it

Your turn

What does this print?

int apples = 3;
double d = apples;
System.out.println(d);
  1. 3
  2. 3.0
  3. 3.00
Show the answer

The int 3 is widened to the double 3.0. Printing a double always shows at least one digit after the point.

Big into small needs a cast

The opposite direction is narrowing and could lose data, so Java demands an explicit cast. If someLong is a long, int i = someLong; doesn't compile. (Casts are the next lesson.)

int i = someLong;        // error
int j = (int) someLong;  // ok, a cast

Range vs precision

float and double cover enormous ranges but keep only a limited number of significant digits: float about 7 (24 bits of precision), double about 15–16 (53 bits). Widening keeps the size of the number, but low digits may be rounded.

🔮 Predict it

Your turn

A long goes into a float and back. What comes out?

long n = 123_456_789L;
float f = n;
System.out.println((long) f);
  1. 123456789
  2. 123456792
  3. Compile error
Show the answer

long → float is legal widening, but float has only 24 bits of precision. 123,456,789 can't be stored exactly, so it's rounded to the nearest float: 123456792.

⚠️ The trap

long → double isn't lossless either

double has 53 bits of precision, while long has 64. Longs above 2⁵³ (about 9 quadrillion) can be rounded when widened to double, silently.

long big = 9_007_199_254_740_993L;
double d = big;
// (long) d is 9007199254740992
💼 In the real world

In real projects

IDs are often 64-bit longs. Push them through a double (some JSON parsers, or JavaScript, where every number is a double) and large IDs silently change. Twitter's API added string IDs (id_str) for exactly this reason.

Key takeaways

  1. Widening happens automatically, with no cast
  2. int → long → float → double never overflows
  3. long → float / double can round off low digits
  4. float keeps ~7 significant digits, double ~15–16
🤯 Did you know?

16,777,217 (2²⁴ + 1) is the smallest positive whole number a float can't store exactly. Every integer up to 2²⁴ fits perfectly.

Practice questions

What does this print?

int i = 7;
double d = i;
System.out.println(d);
  1. 7
  2. 7.00
  3. 7.0
  4. Compile error
Check your answer

7.0. The int is widened to the double 7.0. Printing a double always shows at least one digit after the decimal point.

Which assignment needs an explicit cast? (someLong is a long, someInt an int, someFloat a float)

  1. long l = someInt;
  2. int i = someLong;
  3. double d = someFloat;
  4. float f = someLong;
Check your answer

int i = someLong;. long → int is narrowing and could lose data, so you must write (int). The others are widening conversions that happen automatically.

Next: forcing a big value into a small box with a cast. What's (byte) 300? Hint: it's not 127.