Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Java › Basic syntax

Operators and type conversion

Why is 7 / 2 equal to 3 and not 3.5?

In Java, the result of a calculation is determined not only by the numbers but also by the types. A calculation between two int values gives an int, so the fractional part, or the part that goes beyond the range, is lost, and when the types are mixed, the narrower type is automatically converted to the wider type before the calculation. With +, if either side is a string, the operation is concatenation, not addition.

Checked against real execution · Checked by running 18 pieces of code on JDK 21 (including one compile-time error)

Concepts in this lab

Type conversion
This means changing the type of a value to another type. Converting from a narrower type to a wider type (from int to long, or from int to double) happens automatically, and in a calculation with mixed types, too, the narrower side is converted to the wider type before the calculation. Among the automatic conversions, however, int to float, long to float, and long to double may lose precision for large values. Converting from a wider type to a narrower type can lose information, so you must write the type yourself in parentheses, as in (int), and this is called a cast, or casting. Converting a double to an int discards the fractional part, and converting a large integer to a narrower integer type cuts off the high-order bits, which can give a completely different value. The conversion that happens when a value is stored in a variable is applied to the value after the calculation has finished, so it cannot bring back a part that was already discarded or that overflowed during the calculation.
Integer division and remainder
When an integer is divided by an integer with /, the result is also an integer, and the fractional part is discarded without rounding. The result is truncated toward zero, so 7 / 2 is 3 and -7 / 2 is -3. The % operator gives the remainder of a division, and the sign of the remainder follows the sign of the dividend (the number on the left). Dividing an integer by 0, or taking the remainder with 0, throws an ArithmeticException. To get the fractional part too, convert one side to double before dividing.
Integer overflow
This is what happens when the result of a calculation goes beyond the range that its type can hold and becomes an unexpected value. A Java int can hold -2147483648 through 2147483647, and a result beyond this range crosses over to the opposite end of the range and continues from there, with no exception. For example, adding 1 to 2147483647 gives -2147483648. No error occurs and the wrong value is silently used, so the problem is hard to find. For a calculation that can go out of range, use long, or use a method such as Math.addExact, which throws an exception when the result overflows.
String concatenation
This is what the + operator does when either side of it is a string (String): it does not add, but creates a new string by joining the two values. The side that is not a string is first converted to a string and then joined. When there are several + operators, they are evaluated from the left, in order, so 1 + 2 + "3" becomes "33", which joins 3 and "3", and "1" + 2 + 3 becomes "123". To add the numbers first, put that part in parentheses.

Try these

Running with the default settings

  1. 7 / 2: Both sides are int, so the result is also an int. The mathematical value is 3.5. But an int cannot hold a fractional part, so it is discarded without rounding and only 3 remains.
  2. int r = 3: The calculated value is stored in the int variable r. The types are the same, so the value stays as it is.
  3. System.out.println(r): The value in r is printed. The output is 3.

Result of this run

Code

int r = 7 / 2;                  // int divided by int

System.out.println(r);

Assumptions of this model

The results of the 18 pieces of code (the type of the right-hand expression, the type of the variable, and the output or exception) were checked against the result of running the same code on JDK 21 on this PC. That int r = 3.99 is a compile-time error, and the message it gives, were also confirmed by actually giving the code to the compiler of the same JDK (the message is the one from the English version). The behavior of 7 / 0.0, (double) sum / count, "Sum: " + 1 + 2, n % 2 == 1, Math.round, and Math.addExact, which are mentioned in the summary, was also confirmed by running them. Some things are not covered. Calculations with float, char, and short, the rule that lets an integer constant within the range be stored directly in a narrower type, as in byte b = 100, the error that arises with large numbers when a long is converted to a double, and the error in floating-point calculations such as 0.1 + 0.2 are not included. An expression made only of numbers, such as 7 / 2, is actually evaluated in advance by the compiler, but the result is the same.

Previous lab: Variables and types · Next lab: Conditionals and loops

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these