Java Math Class: Essential Methods with Examples
Introduction
Square roots, powers, rounding, absolute values, random numbers - most programs need a few mathematical operations, and Java provides them in the java.lang.Math class. This tutorial explains the essential methods of the Java Math class with examples. We will start with what the
(Note - This tutorial builds on Java Primitive Data TypesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples and Type Conversion and CastingClick to read tutorial: Type Conversion and Casting in Java with Examples.) What is the Math class?
It has two constants -
OUTPUT of the above code
Explanation of the code
Powers and roots - pow(), sqrt(), cbrt() and hypot()
OUTPUT of the above code
Explanation of the code
OUTPUT of the above code
Explanation of the code
Random numbers - Math.random()
OUTPUT of the above code (the percentages vary slightly from run to run)
Each face came up about one sixth of the time. A
OUTPUT of the above code
Notice the last line:
Trigonometry, logarithms and other methods
OUTPUT of the above code
Math class is and its two constants. We will then look at the basic methods - abs(), max(), min() - and at powers and roots. Next we will compare the four ways of rounding, which are a common source of bugs. We will then generate random numbers, and use the exact methods which detect overflow. Lastly, we will go through the trigonometric and logarithmic methods, and the pitfalls to watch for.(Note - This tutorial builds on Java Primitive Data TypesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples and Type Conversion and CastingClick to read tutorial: Type Conversion and Casting in Java with Examples.) What is the Math class?
java.lang.Math is a class of static methods and constants for numeric calculations. It is in java.lang, so it needs no import. You never create a Math object - its constructor is private - you call its methods on the class itself, such as Math.sqrt(16). (See static vs instance methodsClick to read tutorial: Static vs Instance Methods in Java.)It has two constants -
Math.PI- the ratio of a circle's circumference to its diameter, 3.141592653589793.Math.E- the base of natural logarithms, 2.718281828459045.
double values. Several, such as abs(), max() and min(), are overloadedClick to read tutorial: Method Overloading in Java with Examples for int, long, float and double, and return the same type they are given.
Basic methods - abs(), max(), min() and signum()
abs(), max(), min(), signum() and the constants
//BasicMath.java
public class BasicMath {
public static void main(String[] args) {
System.out.println("Math.abs(-42) = " + Math.abs(-42));
System.out.println("Math.abs(-3.5) = " + Math.abs(-3.5));
System.out.println("Math.max(17, 42) = " + Math.max(17, 42));
System.out.println("Math.min(2.5, -1.0) = " + Math.min(2.5, -1.0));
System.out.println("Math.signum(-8.0) = " + Math.signum(-8.0));
int a = 7, b = 19, c = 11;
System.out.println("Largest of three = " + Math.max(a, Math.max(b, c)));
double radius = 2.5;
System.out.println("Circle area = " + Math.PI * radius * radius);
System.out.println("Math.E = " + Math.E);
}
}
Math.abs(-42) = 42 Math.abs(-3.5) = 3.5 Math.max(17, 42) = 42 Math.min(2.5, -1.0) = -1.0 Math.signum(-8.0) = -1.0 Largest of three = 19 Circle area = 19.634954084936208 Math.E = 2.718281828459045
abs()returns the value without its sign, and keeps the argument's type -Math.abs(-42)is theint42.max()andmin()take exactly two values. To find the largest of three, nest the calls.signum()returns -1.0, 0.0 or 1.0, depending on the sign of its argument.
pow(a, b)- a raised to the power b. Java has no^power operator -^is bitwise XORClick to read tutorial: Java Bitwise and Shift Operators with Examples.sqrt(x)- the square root;cbrt(x)- the cube root.hypot(x, y)- the length of the hypotenuse, √(x² + y²), calculated without overflow for very large values.
Powers and roots
//PowersRoots.java
public class PowersRoots {
public static void main(String[] args) {
System.out.println("Math.pow(2, 10) = " + Math.pow(2, 10));
System.out.println("Math.pow(9, 0.5) = " + Math.pow(9, 0.5));
System.out.println("Math.pow(2, -2) = " + Math.pow(2, -2));
System.out.println("Math.sqrt(144) = " + Math.sqrt(144));
System.out.println("Math.cbrt(27) = " + Math.cbrt(27));
System.out.println("Math.hypot(3, 4) = " + Math.hypot(3, 4));
System.out.println("Math.sqrt(-1) = " + Math.sqrt(-1));
System.out.println("2 ^ 10 (XOR!) = " + (2 ^ 10));
double principal = 1000, rate = 0.05;
int years = 10;
double amount = principal * Math.pow(1 + rate, years);
System.out.printf("1000 at 5%% for 10 years = %.2f%n", amount);
int asInt = (int) Math.pow(2, 10);
System.out.println("(int) Math.pow(2, 10) = " + asInt);
}
}
Math.pow(2, 10) = 1024.0 Math.pow(9, 0.5) = 3.0 Math.pow(2, -2) = 0.25 Math.sqrt(144) = 12.0 Math.cbrt(27) = 3.0 Math.hypot(3, 4) = 5.0 Math.sqrt(-1) = NaN 2 ^ 10 (XOR!) = 8 1000 at 5% for 10 years = 1628.89 (int) Math.pow(2, 10) = 1024
pow()always returns adouble, soMath.pow(2, 10)is1024.0. Cast the result when you need an integer.- A power of 0.5 is a square root, and a negative power is a reciprocal -
2-2is 0.25. - The square root of a negative number is
NaN(Not a Number), not an exception. 2 ^ 10is 8, not 1024 - a classic mistake for programmers coming from languages where^means "power".- For powers of two in integer code, a shift is exact and faster:
1 << 10is 1024.
floor(x)- rounds down, towards negative infinity. Returns adouble.ceil(x)- rounds up, towards positive infinity. Returns adouble.round(x)- rounds to the nearest whole number, with halves rounded up (towards positive infinity). Returns alongfor adoubleargument, and anintfor afloat.rint(x)- rounds to the nearest whole number, with halves rounded to the nearest even number. Returns adouble.
Comparing the rounding methods
//Rounding.java
public class Rounding {
public static void main(String[] args) {
double[] values = {2.4, 2.5, 2.6, 3.5, -2.5, -2.6};
System.out.println("value floor ceil round rint (int) cast");
for (double v : values) {
System.out.printf("%5.1f %6.1f %5.1f %5d %6.1f %6d%n",
v, Math.floor(v), Math.ceil(v), Math.round(v), Math.rint(v), (int) v);
}
double price = 19.98765;
System.out.println("Two decimals (display): " + String.format("%.2f", price));
System.out.println("Two decimals (value) : " + Math.round(price * 100) / 100.0);
int items = 23, perBox = 5;
System.out.println("Boxes needed: " + (int) Math.ceil((double) items / perBox));
System.out.println("Boxes needed (integer): " + Math.ceilDiv(items, perBox));
}
}
value floor ceil round rint (int) cast 2.4 2.0 3.0 2 2.0 2 2.5 2.0 3.0 3 2.0 2 2.6 2.0 3.0 3 3.0 2 3.5 3.0 4.0 4 4.0 3 -2.5 -3.0 -2.0 -2 -2.0 -2 -2.6 -3.0 -2.0 -3 -3.0 -2 Two decimals (display): 19.99 Two decimals (value) : 19.99 Boxes needed: 5 Boxes needed (integer): 5
Math.round(-2.5)is -2, not -3, because halves go up towards positive infinity.rint()sends halves to the even neighbour, so 2.5 becomes 2.0 and 3.5 becomes 4.0 - this banker's rounding avoids bias when many values are rounded.- A
(int)cast is not rounding at all - it just drops the fractional part, towards zero. - To display a value with two decimals, use
String.format(). Rounding the value itself withMath.round(x * 100) / 100.0works for simple cases, but for money use BigDecimalClick to read tutorial: BigInteger and BigDecimal in Java with Examples. Math.ceilDiv()(Java 18+) divides integers rounding up, without converting todouble- ideal for "how many boxes" or "how many pages" calculations.
Math.random() returns a random double from 0.0 (inclusive) up to, but not including, 1.0. To get a whole number in a range, scale and cast it: (int) (Math.random() * n) gives 0 to n - 1. For anything more, the java.util.Random class and ThreadLocalRandom are easier, and accept a range directly.
Generating random numbers
//RandomNumbers.java
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class RandomNumbers {
public static void main(String[] args) {
double r = Math.random();
System.out.println("0.0 <= r < 1.0 : " + (r >= 0.0 && r < 1.0));
int[] counts = new int[7];
for (int i = 0; i < 60_000; i++) {
int die = (int) (Math.random() * 6) + 1; // 1 to 6
counts[die]++;
}
for (int face = 1; face <= 6; face++) {
System.out.printf("face %d: about %.1f%%%n", face, counts[face] / 600.0);
}
Random seeded = new Random(42); // the same seed gives the same sequence
System.out.println("Seeded Random : " + seeded.nextInt(100) + " " + seeded.nextInt(100) + " " + seeded.nextInt(100));
int between = ThreadLocalRandom.current().nextInt(10, 21); // 10 to 20
System.out.println("10 <= between <= 20 : " + (between >= 10 && between <= 20));
}
}
0.0 <= r < 1.0 : true face 1: about 16.6% face 2: about 16.6% face 3: about 16.7% face 4: about 16.6% face 5: about 16.6% face 6: about 16.9% Seeded Random : 30 63 48 10 <= between <= 20 : true
Random created with a seed always produces the same sequence - useful for repeatable tests and simulations. None of these is suitable for passwords or security tokens; use java.security.SecureRandom for those.
Detecting overflow - the exact methods
Integer arithmetic silently wraps around on overflow, as explained in primitive data typesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples. The exact methods - addExact(), subtractExact(), multiplyExact(), incrementExact(), negateExact() and toIntExact() - do the same calculations but throw an ArithmeticException instead of returning a wrong answer.
Catching overflow with the exact methods
//ExactMath.java
public class ExactMath {
public static void main(String[] args) {
int bigValue = 2_000_000_000;
System.out.println("bigValue * 2 = " + (bigValue * 2));
try {
System.out.println("multiplyExact(bigValue, 2) = " + Math.multiplyExact(bigValue, 2));
} catch (ArithmeticException e) {
System.out.println("multiplyExact threw : " + e.getMessage());
}
System.out.println("multiplyExact as long = " + Math.multiplyExact((long) bigValue, 2));
long fileSize = 5_000_000_000L;
try {
int size = Math.toIntExact(fileSize);
} catch (ArithmeticException e) {
System.out.println("toIntExact threw : " + e.getMessage());
}
System.out.println("Math.abs(Integer.MIN_VALUE) = " + Math.abs(Integer.MIN_VALUE));
}
}
bigValue * 2 = -294967296 multiplyExact threw : integer overflow multiplyExact as long = 4000000000 toIntExact threw : integer overflow Math.abs(Integer.MIN_VALUE) = -2147483648
Math.abs(Integer.MIN_VALUE) is still negative, because +2,147,483,648 does not fit in an int. Math.absExact() (Java 15+) throws an exception in that case instead.
sin(),cos(),tan(),asin(),acos(),atan()andatan2(y, x)work in radians. Convert withtoRadians()andtoDegrees().log(x)- natural logarithm (base e);log10(x)- base 10;exp(x)- ex.floorDiv()andfloorMod()- integer division and remainder which round towards negative infinity, sofloorMod(-1, 7)is 6, not -1 - handy for wrapping around days of the week or clock hours.clamp(value, min, max)(Java 21+) - keeps a value within a range.
Trigonometric, logarithmic and other methods
//OtherMath.java
public class OtherMath {
public static void main(String[] args) {
System.out.println("sin(30 deg) = " + Math.sin(Math.toRadians(30)));
System.out.println("cos(60 deg) = " + Math.cos(Math.toRadians(60)));
System.out.println("atan2(1, 1) = " + Math.toDegrees(Math.atan2(1, 1)) + " degrees");
System.out.println("log(E) = " + Math.log(Math.E));
System.out.println("log10(1000) = " + Math.log10(1000));
System.out.println("digits in 98765 = " + ((int) Math.log10(98765) + 1));
System.out.println("-1 % 7 = " + (-1 % 7));
System.out.println("floorMod(-1, 7) = " + Math.floorMod(-1, 7));
System.out.println("clamp(150, 0, 100) = " + Math.clamp(150, 0, 100));
}
}
sin(30 deg) = 0.49999999999999994 cos(60 deg) = 0.5000000000000001 atan2(1, 1) = 45.0 degrees log(E) = 1.0 log10(1000) = 3.0 digits in 98765 = 5 -1 % 7 = -1 floorMod(-1, 7) = 6 clamp(150, 0, 100) = 100
sin(30°) printed 0.49999999999999994 instead of 0.5 - another reminder that floating-point results are approximations. Compare them with a small tolerance, never with ==.
Summary
In this tutorial we first saw that java.lang.Math is a class of static methods, with the constants PI and E. We then used abs(), max(), min() and signum(), and calculated powers and roots - remembering that ^ is not a power operator. Next we compared floor(), ceil(), round() and rint(), and saw how they treat halves and negative numbers. We then generated random numbers, and caught overflow with the exact methods. Lastly, we used the trigonometric and logarithmic methods, floorMod() and clamp(). In the next tutorial, we will calculate exactly, without rounding errors or overflow, using BigInteger and BigDecimalClick to read tutorial: BigInteger and BigDecimal in Java with Examples.