Java Numbers

Su Suriya Ravichandran Updated 14 Nov 2026
5 min read ·Lesson 12 of 133

Java represents numbers in two families: integer types for whole numbers and floating-point types for numbers with a fractional part. Choosing between them affects range, precision, and whether arithmetic is exact.

Integer Types

TypeBitsMinimumMaximum
byte8−128127
short16−32,76832,767
int32−2,147,483,6482,147,483,647
long64−9,223,372,036,854,775,8089,223,372,036,854,775,807
int population = 1_400_000_000;
long distanceToSunMeters = 149_597_870_700L;
byte flags = 0b0000_0101;
short year = 2026;

int is the default choice. Use long when a value can exceed about ±2.1 billion: timestamps in milliseconds, file sizes in bytes, large database IDs. The L suffix is required for a long literal larger than int range, because unsuffixed integer literals are int.

Literal forms

int decimal = 255;
int hex = 0xFF;          // 255, prefix 0x
int binary = 0b11111111; // 255, prefix 0b
int octal = 0377;        // 255, leading 0 means octal
int readable = 1_000_000;

The octal form is a trap: int code = 010; is 8, not 10. Never write a leading zero on a decimal number. Underscores are purely visual and may appear only between digits.

Overflow

Integer arithmetic wraps around when it exceeds the type's range. No error is raised.

int max = Integer.MAX_VALUE;
System.out.println(max + 1);              // -2147483648

int millis = 30 * 24 * 60 * 60 * 1000;    // milliseconds in 30 days
System.out.println(millis);               // -1702967296 (overflowed)

long correct = 30L * 24 * 60 * 60 * 1000; // 2592000000

In the second example every operand is an int, so the multiplication happens in 32-bit arithmetic and overflows before the result is stored. Making the first operand a long (30L) promotes the whole calculation to 64 bits. Assigning an overflowed int result to a long variable does not help; the damage is done in the expression.

To detect overflow instead of wrapping silently, use the exact methods:

int total = Math.addExact(a, b);        // throws ArithmeticException on overflow
long product = Math.multiplyExact(x, y);

Floating-Point Types

TypeBitsApprox. rangeSignificant decimal digits
float32±3.4 × 10³⁸6–7
double64±1.8 × 10³⁰⁸15–16
double pi = 3.141592653589793;
float ratio = 0.75f;
double avogadro = 6.022e23;     // scientific notation: 6.022 × 10²³
double tiny = 1.6e-19;

Decimal literals are double by default; float requires the f suffix. double is the standard choice; float is used mainly for memory-heavy arrays and graphics APIs.

Precision limits

Floating-point numbers are stored in binary, and most decimal fractions have no exact binary representation, just as 1/3 has no exact decimal one.

System.out.println(0.1 + 0.2);            // 0.30000000000000004
System.out.println(1.1 * 3);              // 3.3000000000000003
System.out.println(0.1 + 0.2 == 0.3);     // false

Compare floating-point values with a tolerance:

double a = 0.1 + 0.2;
double b = 0.3;
boolean close = Math.abs(a - b) < 1e-9;   // true

For money and anything that must be exact in decimal, use BigDecimal (covered in its own lesson) constructed from a string:

import java.math.BigDecimal;

BigDecimal price = new BigDecimal("0.10");
BigDecimal total = price.add(new BigDecimal("0.20"));
System.out.println(total);   // 0.30

Special values

System.out.println(1.0 / 0);       // Infinity
System.out.println(-1.0 / 0);      // -Infinity
System.out.println(0.0 / 0);       // NaN
System.out.println(Math.sqrt(-1)); // NaN

Floating-point division by zero does not throw. NaN ("not a number") propagates through every calculation it touches and is not equal to anything, including itself, so test with Double.isNaN(x). Double.isFinite(x) checks that a value is neither infinite nor NaN.

Integer Versus Floating-Point Arithmetic

The type of the operands decides the kind of arithmetic:

System.out.println(10 / 4);      // 2      (int / int)
System.out.println(10 / 4.0);    // 2.5    (int / double)
System.out.println(10.0 / 4);    // 2.5
System.out.println(10 % 4);      // 2
System.out.println(10.5 % 4);    // 2.5

To get a decimal result from two integer variables, cast one before dividing:

int correct = 47, total = 60;
double percent = (double) correct / total * 100;   // 78.333...

(double) (correct / total) would be wrong: the integer division happens first and yields 0.

Number Wrapper Classes

Each numeric primitive has a wrapper class (Integer, Long, Double, ...) that provides constants and conversion methods:

System.out.println(Integer.MAX_VALUE);          // 2147483647
System.out.println(Long.MIN_VALUE);             // -9223372036854775808
System.out.println(Double.MAX_VALUE);           // 1.7976931348623157E308

int n = Integer.parseInt("123");
double d = Double.parseDouble("4.56");
String bin = Integer.toBinaryString(10);        // "1010"
String hex = Integer.toHexString(255);          // "ff"
int fromHex = Integer.parseInt("ff", 16);       // 255
int cmp = Integer.compare(3, 7);                // negative

Wrappers are required wherever an object is needed, such as in collections (List<Integer>), and the compiler converts between primitives and wrappers automatically. The wrapper classes each have their own lesson.

Practical Example: Loan Interest

public class LoanCalculator {
    public static void main(String[] args) {
        long principal = 500_000;       // whole currency units
        double annualRate = 8.5;        // percent
        int years = 5;

        double monthlyRate = annualRate / 12 / 100;
        int months = years * 12;

        double emi = principal * monthlyRate * Math.pow(1 + monthlyRate, months)
                / (Math.pow(1 + monthlyRate, months) - 1);

        double totalPaid = emi * months;
        double interest = totalPaid - principal;

        System.out.printf("Monthly EMI:    %,.2f%n", emi);
        System.out.printf("Total paid:     %,.2f%n", totalPaid);
        System.out.printf("Total interest: %,.2f%n", interest);
    }
}

Output:

Monthly EMI:    10,258.27
Total paid:     615,495.94
Total interest: 115,495.94

principal is a long because loan amounts can exceed int range in some currencies. The rate is a double because it is fractional. annualRate / 12 / 100 is computed in double since annualRate is a double; had it been an int, both divisions would truncate to 0. Math.pow returns a double. %,.2f prints two decimals with thousands separators. Note that the total is computed from the unrounded EMI; a bank charging exactly 10,258.27 each month would collect 615,496.20, which is why real banking systems round each payment with BigDecimal and track the difference explicitly.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about Java Numbers and get answers drawn from it.

Signed-in readers only.