Unit 1 · 20 min

1.5 Casting and Range of Variables

Converting between int and double changes values in predictable ways, and both types have limits.

Summary, objectives and course and exam description (CED) codes

The casting operators (int) and (double) convert between double and int values: casting to int truncates the decimal part, and int values are widened to double automatically. An int must lie between Integer.MIN_VALUE and Integer.MAX_VALUE, or integer overflow occurs. A double has limited precision, so round-off error can occur.

By the end of this session you can

  • 1.5.A Develop code to cast primitive values to different primitive types in arithmetic expressions and determine the value that is produced as a result.
  • 1.5.B Describe conditions when an integer expression evaluates to a value out of range.
  • 1.5.C Describe conditions that limit accuracy of expressions.

1.5.A1.5.A.11.5.A.21.5.A.31.5.A.41.5.B1.5.B.11.5.B.21.5.B.31.5.C1.5.C.1

Reviewed against the CED on

Know this already? Jump to the checkpoint.

1LearnThe notes, the traps and how to remember them

1. The casting operators

The 2 casting operators are (int) and (double). They convert a double value to an int value, or an int value to a double value 1.5.A.1. Casting a double to an int causes the digits to the right of the decimal point to be truncated (cut off) 1.5.A.2. Truncating moves toward zero, for negative numbers too.

A cast is a one-operand operator, so it applies only to the value right after it (see the precedence table in topic 1.3).

Code Result Rule
(int) 3.86 3 casting to int truncates (cuts off) the decimal part
(int) -3.86 -3 truncating moves toward zero for negatives too
(double) 7 / 2 3.5 the cast happens first, so this is 7.0 / 2
(double) (7 / 2) 3.0 7 / 2 is already 3 before the cast
double d = 7; 7.0 an int is automatically cast (widened) to double
(int) (3.86 + 0.5) 4 rounds a non-negative double to the nearest int
(int) (-3.86 - 0.5) -4 rounds a negative double to the nearest int
System.out.println((int) 3.86);
System.out.println((int) -3.86);
System.out.println((double) 7 / 2);
System.out.println((double) (7 / 2));
double d = 7;
System.out.println(d);
System.out.println((int) (3.86 + 0.5));
System.out.println((int) (-3.86 - 0.5));

Output:

3
-3
3.5
3.0
7.0
4
-4

2. Widening: int to double automatically

Some code causes int values to be automatically cast (widened) to double values 1.5.A.3. This happens when you store an int in a double variable, or when an int meets a double in an expression.

int steps = 7;
double km = steps;          // widened to 7.0
System.out.println(km);
System.out.println(steps * 1.5);

Output:

7.0
10.5

The other direction is never automatic, because it could lose information. A double cannot be stored in an int variable without a cast:

// does not compile
int k = 3.5;

Real view:

error: incompatible types: possible lossy conversion from double to int

int k = (int) 3.5; compiles and stores 3.

3. Rounding to the nearest integer

Values of type double can be rounded to the nearest integer with (int) (x + 0.5) for non-negative numbers or (int) (x - 0.5) for negative numbers 1.5.A.4.

double rating = 4.7;
double drop = -2.6;
System.out.println((int) rating);
System.out.println((int) (rating + 0.5));
System.out.println((int) (drop - 0.5));

Output:

4
5
-3

Watch out: the parentheses matter. (int) rating + 0.5 casts first, giving 4 + 0.5, which is the double 4.5.

4. The range of int and integer overflow

The constant Integer.MAX_VALUE holds the largest possible int value, and Integer.MIN_VALUE holds the smallest 1.5.B.1. An int is stored in a fixed amount of memory (4 bytes), so every int value must lie in the range from Integer.MIN_VALUE (-2147483648) to Integer.MAX_VALUE (2147483647), inclusive 1.5.B.2.

If an expression would evaluate to an int outside this range, integer overflow occurs. The result is still an int in the allowed range, but not necessarily the value you expected 1.5.B.3. No error is reported; the program keeps running with the wrong value.

int big = Integer.MAX_VALUE;
System.out.println(big);
System.out.println(big + 1);
System.out.println(big + 2);
System.out.println(Integer.MIN_VALUE);

Output:

2147483647
-2147483648
-2147483647
-2147483648

5. Round-off error with double

Computers give each data type a fixed amount of memory. A double also has limited memory. When an expression would produce a double that is more precise than can be stored, a round-off error occurs, and the result is rounded to the nearest representable value. To avoid these rounding errors, use int values where you can, for example by storing money in cents 1.5.C.1.

System.out.println(0.1 + 0.2);
int cents = 10 + 20;
System.out.println(cents + " cents");

Output:

0.30000000000000004
30 cents

Outside the course: other special decimal types that avoid rounding errors.

Background (not tested): why 0.1 is not exact. Computers store numbers in binary (base 2). Just as 1/3 never ends in decimal (0.333…), 1/10 never ends in binary, so a double holds a value very close to 0.1, not exactly 0.1. Tiny errors like this are why you should not test double values with == (Unit 2).

Lock it in: memory hooks

  • Truncation(int) is scissors, not a calculator: it cuts the decimals off.
  • RoundingAdd half, then cut: (int) (x + 0.5).
  • OverflowPast the top of the int range, the value wraps around to the bottom.

Common misconceptions

  • "(int) rounds to the nearest whole number."

    Not quite. (int) truncates: it cuts off the digits after the decimal point. (int) 9.99 is 9. To round a non-negative value, use (int) (x + 0.5).

  • "Integer overflow causes an error message."

    Not quite. No error is reported. The result is still an int in the allowed range, but not the value you expected, and the program keeps running.

  • "(double) (7 / 2) is 3.5."

    Not quite. The parentheses make 7 / 2 happen first, as int division, giving 3. Casting 3 gives 3.0. Write (double) 7 / 2 to get 3.5.

  • "A double stores every decimal value exactly."

    Not quite. A double has a limited amount of memory. Values such as 0.1 cannot be stored exactly, so 0.1 + 0.2 prints 0.30000000000000004.

Exam traps

  • (int) does not round. (int) 9.99 is 9. To round, add 0.5 first (or subtract 0.5 for negative numbers).
  • A double cannot be stored in an int variable without a cast. int k = 3.5; does not compile; int k = (int) 3.5; stores 3. The other way is automatic: double d = 7; stores 7.0.
  • A cast applies only to the value right after it: (double) 7 / 2 is 3.5, but (double) (7 / 2) is 3.0.
  • Integer overflow is not an exception. Integer.MAX_VALUE + 1 is a large negative int, with no error.

2PracticeRecall it, then check yourself

In 30 seconds

  1. (int) and (double) convert between double and int values.
  2. Casting a double to an int truncates the digits after the decimal point (toward zero).
  3. int values are automatically cast (widened) to double when needed, as in double d = 7;.
  4. Round to the nearest int with (int) (x + 0.5) for non-negative x or (int) (x - 0.5) for negative x.
  5. An int uses 4 bytes and must be from Integer.MIN_VALUE to Integer.MAX_VALUE; going past that range is integer overflow.
  6. A double result that is too precise to store is rounded: round-off error. Use int values to avoid it.

Cover this list, say the points out loud, then take the checkpoint without scrolling back up.

Checkpoint · 5 questions

Checkpoint: Casting and Range of Variables

Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.

  1. 1 What is printed? 1.5.A.1, 1.5.A.2, 1.5.A.3
    double price = 12.99;
    int whole = (int) price;
    double back = whole;
    System.out.println(whole + " " + back);
    Show answer

    Answer: A. (int) truncates 12.99 to 12; assigning 12 to a double widens it to 12.0. B rounds instead of truncating. C assumes back keeps the decimals, but the decimals were lost in whole. D prints whole as a double, but it is an int.

  2. 2 What value is stored in r? 1.5.A.1, 1.5.A.2, 1.3.C.5
    double r = (int) 7.9 / 2.0 - -1;
    Show answer

    Answer: B. The cast applies to 7.9 only: (int) 7.9 is 7, 7 / 2.0 is 3.5, and 3.5 - -1 is 4.5. C casts after dividing (3.5 becomes 3, then 3 + 1 is 4.0). D reads - -1 as subtracting 1. A ignores the cast (7.9 / 2.0 is 3.95, plus 1).

  3. 3 An int variable big holds Integer.MAX_VALUE. Which best describes the result of big + 1? 1.5.B.1, 1.5.B.2, 1.5.B.3
    Show answer

    Answer: D. Integer overflow gives an int in range, but not the expected value. No exception occurs, so C is wrong. A is wrong because the compiler does not know the run-time value of big. B is wrong because int + int is always an int; Java does not switch to double.

  4. 4 System.out.println(0.1 + 0.2 == 0.3); prints false. Which best explains why? 1.5.C.1
    Show answer

    Answer: A. 0.1 and 0.2 cannot be stored exactly in a double, so round-off error makes the sum differ from 0.3 (it is 0.30000000000000004). B is wrong because no int values are involved. C is wrong because == does not round anything. D is wrong because == does compile with numbers; it just compares the stored values exactly.

  5. 5 Consider the following code segment. What is printed? 1.5.A.4, 1.5.A.2
    double temp = -6.7;
    int rounded = (int) (temp - 0.5);
    System.out.println(rounded);
    Show answer

    Answer: C. -6.7 - 0.5 is -7.2, and casting truncates toward zero, giving -7: the nearest integer to -6.7. A is the result of truncating -6.7 without subtracting 0.5. B rounds away from zero one step too far. D is impossible, because rounded is an int and cannot hold -7.2.

3PrevailLock it in for exam day

By the numbers

Name each list from memory, then reveal it to check. Each list shows how many items to recall.

  • Casting operators two operators CED 1.5.A.1
    1. int
    2. double
  • Limits of an int, which is stored in 4 bytes of memory (range inclusive) two constants CED 1.5.B.1, 1.5.B.2
    1. Integer.MIN_VALUE-2147483648, the smallest int
    2. Integer.MAX_VALUE2147483647, the largest int
  • Rounding formulas two formulas CED 1.5.A.4
    1. (int) (x + 0.5) for non-negative x
    2. (int) (x - 0.5) for negative x

Key terms: flip the cards

Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.

  • Castingtap to flip

    Converting a value between double and int with the casting operators (int) and (double).

    Example and CED codes
  • Truncationtap to flip

    Cutting off the digits to the right of the decimal point, as (int) does when it casts a double to an int.

    Example and CED codes
  • Wideningtap to flip

    The automatic conversion of an int value to a double value, such as when an int is stored in a double variable.

    Example and CED codes
  • Integer overflowtap to flip

    What happens when an int expression would go outside the range Integer.MIN_VALUE to Integer.MAX_VALUE: the result is an int in range, but not the expected value.

    Example and CED codes
  • Round-off errortap to flip

    An error that occurs when a double result is more precise than can be stored, so the value is rounded to a representable one.

    Example and CED codes
  • inttap to flip

    The primitive type for integers, such as -4, 0 or 120. An int is stored in 4 bytes.

    Example and CED codes
  • doubletap to flip

    The primitive type for real numbers, such as 3.75 or -0.5.

    Example and CED codes

Questions students ask

Does casting to int round in Java?

No. Casting a double to an int truncates, which means it cuts off everything after the decimal point. (int) 3.86 is 3 and (int) -3.86 is -3.

How do you round a double to the nearest int in Java?

For a non-negative number x, use (int) (x + 0.5). For a negative number, use (int) (x - 0.5). For example, (int) (3.86 + 0.5) is 4.

What is integer overflow?

An int is stored in 4 bytes, so it must lie between Integer.MIN_VALUE and Integer.MAX_VALUE. If an expression would go past that range, the result is still an int in the range but not the expected value. No error is reported.

Why does 0.1 + 0.2 not equal 0.3 in Java?

A double has a limited amount of memory, and 0.1 and 0.2 cannot be stored exactly. The tiny round-off errors add up, so the sum is 0.30000000000000004.

Was this page helpful?

No names are ever shown, and every public comment is checked by us first. Please do not include personal details. To get a reply, email [email protected].

↑ Top

Enlarged view of the selected figure