Operators & Math
An operator is a symbol that does something with values: + adds, > compares, && combines two conditions. The values an operator works on are called operands. Java's operators look like school maths, but a few behave in surprising ways, especially division with whole numbers.
In this lesson you will learn every operator you need day to day, then use the built-in Math class for powers, square roots and rounding, and finally see how to handle money correctly with BigDecimal.
Arithmetic operators
Java has five arithmetic operators: + (add), - (subtract), * (multiply), / (divide) and % (remainder, also called modulo).
public class Arithmetic {
public static void main(String[] args) {
int laddoos = 17;
int friends = 5;
System.out.println("Each friend gets: " + laddoos / friends);
System.out.println("Left over: " + laddoos % friends);
System.out.println("Exact share: " + laddoos / (double) friends);
System.out.println(7 / 2 + " vs " + 7 / 2.0);
System.out.println(2 + 3 * 4);
System.out.println((2 + 3) * 4);
System.out.println(-17 % 5);
}
}Each friend gets: 3 Left over: 2 Exact share: 3.4 3 vs 3.5 14 20 -2
The most important rule: when both operands are whole numbers, / does integer division and throws away the remainder. 17 / 5 is 3, not 3.4. If at least one operand is a double, you get a decimal result, which is why laddoos / (double) friends gives 3.4.
The % operator gives the remainder after division. It is surprisingly useful: n % 2 == 0 checks whether a number is even, and n % 10 gives the last digit. With a negative left operand, the result is negative too (-17 % 5 is -2).
Java follows the usual order of operations: *, / and % happen before + and -. Use brackets whenever the order is not obvious; they cost nothing and make code clearer.
Assignment, increment and decrement
Besides plain =, Java has compound assignment operators that update a variable in place: +=, -=, *=, /= and %=. The ++ operator adds one and -- subtracts one.
public class Assign {
public static void main(String[] args) {
int wallet = 500;
wallet -= 120; // bought a book
wallet += 50; // got change back
wallet *= 2; // pocket money doubled
System.out.println("Wallet: Rs " + wallet);
int overs = 5;
overs++;
System.out.println("Overs: " + overs);
int a = 10;
int b = a++; // b gets 10, then a becomes 11
int c = ++a; // a becomes 12 first, then c gets 12
System.out.println(a + " " + b + " " + c);
}
}Wallet: Rs 860 Overs: 6 12 10 12
wallet -= 120 is short for wallet = wallet - 120. With ++, position matters only when you use the result in the same expression: a++ (postfix) gives the old value and then increases a, while ++a (prefix) increases first. To avoid confusion, use ++ on its own line, as with overs++.
Comparison, logical and ternary operators
Comparison operators compare two values and give a boolean: == (equal), != (not equal), >, <, >= and <=. Logical operators combine booleans: && (and: both must be true), || (or: at least one must be true) and ! (not: flips true and false).
The ternary operator condition ? valueIfTrue : valueIfFalse picks one of two values in a single expression.
public class Compare {
public static void main(String[] args) {
int age = 17;
int marks = 82;
boolean hasPass = true;
System.out.println(age >= 18);
System.out.println(marks != 100);
System.out.println(marks > 75 && hasPass);
System.out.println(age >= 18 || hasPass);
System.out.println(!hasPass);
String result = marks >= 33 ? "Pass" : "Fail";
System.out.println(result);
}
}false true true true false Pass
&& and || are short-circuit operators: if the left side already decides the answer, the right side is never evaluated. You will use these constantly in if & else. One warning: == compares numbers and booleans correctly, but for strings you must use .equals(), as the strings lesson explains.
The Math class
The class java.lang.Math holds ready-made maths methods. You do not need to import it or create an object: call the methods on the class name.
public class MathDemo {
public static void main(String[] args) {
System.out.println(Math.max(72, 89));
System.out.println(Math.min(72, 89));
System.out.println(Math.abs(-450));
System.out.println(Math.pow(2, 10));
System.out.println(Math.sqrt(144));
System.out.println(Math.round(4.5) + " " + Math.round(4.49));
System.out.println(Math.floor(9.8) + " " + Math.ceil(9.2));
System.out.println(Math.PI);
double radius = 7;
double area = Math.PI * radius * radius;
System.out.println("Area: " + Math.round(area * 100) / 100.0);
int volume = Math.clamp(130, 0, 100); // Java 21+
System.out.println("Volume: " + volume);
}
}89 72 450 1024.0 12.0 5 4 9.0 10.0 3.141592653589793 Area: 153.94 Volume: 100
Note that Math.pow and Math.sqrt always return a double, which is why you see 1024.0. Math.round rounds to the nearest whole number (halves go up), Math.floor goes down and Math.ceil goes up. The trick Math.round(area * 100) / 100.0 rounds to two decimal places. Math.clamp, added in Java 21, keeps a value inside a range: 130 is pulled back to the maximum of 100.
Random numbers
For random numbers, create a java.util.Random object and call nextInt(origin, bound). The result includes the origin but not the bound, so nextInt(1, 7) simulates a dice roll from 1 to 6. You may also see the older Math.random(), which returns a double from 0.0 up to (but not including) 1.0.
import java.util.Random;
public class Dice {
public static void main(String[] args) {
Random random = new Random();
int roll = random.nextInt(1, 7); // 1 to 6
double chance = Math.random(); // 0.0 up to (not including) 1.0
System.out.println("You rolled " + roll);
System.out.println("Random fraction: " + chance);
}
}The output changes every run, for example:
You rolled 5
Random fraction: 0.668001518701434The two-argument nextInt(origin, bound) arrived in Java 17. In older code you will see random.nextInt(6) + 1, which does the same job.
Overflow and money
Every number type has limits. When an int calculation goes past about 2.1 billion, Java does not stop with an error: the value silently wraps around to a large negative number. Decimal types have a different problem: double stores numbers in binary, so many decimal fractions, like 0.1, cannot be stored exactly.
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Money {
public static void main(String[] args) {
int max = Integer.MAX_VALUE;
System.out.println(max + 1);
System.out.println(0.1 + 0.2);
BigDecimal price = new BigDecimal("1299.50");
BigDecimal gst = price.multiply(new BigDecimal("0.18"))
.setScale(2, RoundingMode.HALF_UP);
BigDecimal total = price.add(gst);
System.out.println("GST: " + gst + ", Total: " + total);
}
}-2147483648 0.30000000000000004 GST: 233.91, Total: 1533.41
For whole numbers that might get large, use long, or use Math.addExact and Math.multiplyExact, which stop the program with ArithmeticException: integer overflow instead of silently giving a wrong answer.
For money, use BigDecimal from java.math. It stores decimal numbers exactly. Always create it from a string (new BigDecimal("1299.50")), because new BigDecimal(0.1) copies the inexact double value. Billing, banking and GST code in real companies uses BigDecimal or stores amounts as whole paise in a long.
Common mistakes
- Integer division by accident.
int average = (70 + 85 + 90) / 3;is fine, butdouble half = 1 / 2;gives0.0because1 / 2is integer division done before the assignment. Write1 / 2.0or1.0 / 2. - Dividing an int by zero.
10 / 0stops the program withArithmeticException: / by zero. With doubles,10 / 0.0quietly givesInfinity. - Using
=instead of==.=assigns;==compares. - Expecting
Math.roundto return an int.Math.round(double)returns along, soint r = Math.round(4.5);does not compile without a cast. - Using
doublefor money. Rounding errors add up. UseBigDecimal.
Key points
- Arithmetic operators are
+ - * / %; with two whole numbers,/drops the remainder. +=,-=and friends update a variable;++and--add or subtract one.- Comparison operators give a
boolean;&&,||and!combine booleans and short-circuit. cond ? a : bchooses between two values.Mathprovidesmax,min,abs,pow,sqrt,round,floor,ceil,clampandPI.intoverflow wraps silently;doublecannot store most decimals exactly; useBigDecimalfor money.
Exercise
Rohan scored 78, 91 and 66 in three tests. Write Marks.java that prints the total, the average as a decimal, the average rounded to the nearest whole number, the highest score (use Math.max twice) and Distinction if the average is at least 75, otherwise First class (use the ternary operator).
Show solution
public class Marks {
public static void main(String[] args) {
int t1 = 78, t2 = 91, t3 = 66;
int total = t1 + t2 + t3;
double average = total / 3.0;
System.out.println("Total: " + total);
System.out.println("Average: " + average);
System.out.println("Rounded: " + Math.round(average));
System.out.println("Highest: " + Math.max(t1, Math.max(t2, t3)));
System.out.println(average >= 75 ? "Distinction" : "First class");
}
}Total: 235 Average: 78.33333333333333 Rounded: 78 Highest: 91 Distinction
Dividing by 3.0 instead of 3 makes the division decimal. You can declare several variables of the same type on one line, separated by commas, as in int t1 = 78, t2 = 91, t3 = 66;.
Quick Quiz
1. What does 17 / 4 give in Java?
Both operands are int, so Java does integer division and drops the remainder.
2. What does 17 % 4 give?
% gives the remainder: 17 = 4 × 4 + 1.
3. After int x = 5; int y = x++;, what are x and y?
Postfix x++ gives the old value (5) to y, then increases x to 6.
4. Which type should you use to calculate GST on a bill?
BigDecimal stores decimal amounts exactly; float and double cause rounding errors.
Learn Java with a mentor
Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
