Double Class

Su Suriya Ravichandran Updated 14 Nov 2026
6 min read ·Lesson 107 of 133

double is Java's default floating-point type: a 64-bit IEEE 754 double-precision number with about 15–16 significant decimal digits and an enormous range. java.lang.Double is its wrapper class, providing constants, parsing, comparison, and tests for special values. double is the right choice for measurements, statistics, scientific values, geometry, and percentages. It is the wrong choice for money and anything else that must match decimal arithmetic exactly.

Declaring double Values

Any literal with a decimal point or exponent is a double:

double price = 499.99;
double rate = 0.075;
double avogadro = 6.022e23;
double tiny = 1.6e-19;
double fromInt = 42;          // int widens to double automatically
double explicit = 3d;         // optional d/D suffix

How double Stores Numbers

 1 bit    11 bits          52 bits
[sign] [ exponent ] [   fraction (mantissa)   ]

With 52 stored fraction bits plus an implicit leading 1, a double has 53 bits of precision. That allows exact representation of every integer up to 2⁵³ (9,007,199,254,740,992), and about 15–16 significant decimal digits for other values.

double big = (double) (1L << 53);
System.out.println(big + 1 == big);       // true: above 2^53, adding 1 can be lost
Math.ulp(1.0);                            // 2.220446049250313E-16: gap between 1.0 and the next double

Decimal fractions are approximations

System.out.println(0.1 + 0.2);            // 0.30000000000000004
System.out.println(new BigDecimal(2.675));
// 2.67499999999999982236431605997495353221893310546875

The double written as 2.675 is actually slightly less than 2.675, because 2.675 has no exact binary form. new BigDecimal(double) reveals the exact stored value.

How doubles Are Printed

Double.toString (used by println and concatenation) prints the shortest decimal that uniquely identifies the value, switching to scientific notation for very large or very small magnitudes:

System.out.println(100.0);          // 100.0
System.out.println(12345678.9);     // 1.23456789E7   (≥ 10^7: scientific)
System.out.println(0.001);          // 0.001
System.out.println(0.0001);         // 1.0E-4         (< 10^-3: scientific)

For user-facing output, always format explicitly:

String.format("%.2f", 12345678.9);      // "12345678.90"
String.format("%,.2f", 12345678.9);     // "12,345,678.90"

Constants and Special Values

ConstantValue
Double.MAX_VALUE1.7976931348623157E308
Double.MIN_VALUE4.9E-324 (smallest positive value)
Double.MIN_NORMAL2.2250738585072014E-308
Double.POSITIVE_INFINITY, NEGATIVE_INFINITYResults of overflow or x / 0.0
Double.NaNResult of undefined operations such as 0.0 / 0.0 or Math.sqrt(-1)
Double.isNaN(0.0 / 0.0);          // true
Double.isInfinite(1.0 / 0);       // true
Double.isFinite(42.0);            // true

Division by zero with doubles does not throw: it produces Infinity or NaN, which then silently spread through later calculations. Check results with Double.isFinite at boundaries where invalid values must not pass, such as before storing a computed average or sending it to a client.

NaN != NaN is always true, so test with Double.isNaN, never ==. As with Float, Double.compare and Double.equals treat NaN as equal to itself and order -0.0 before 0.0, which is what sorting and collections need.

Rounding

MethodRule2.5-2.5-2.7
Math.round(x)Nearest; halves round up (toward +∞); returns long3-2-3
Math.rint(x)Nearest; halves round to the even neighbor; returns double2.0-2.0-3.0
Math.floor(x)Down, toward −∞2.0-3.0-3.0
Math.ceil(x)Up, toward +∞3.0-2.0-2.0
(long) xTruncate toward zero2-2-2

To round to a number of decimal places for display, use formatting (%.2f) or BigDecimal. Avoid tricks like Math.round(x * 100) / 100.0 for anything important: the intermediate multiplication introduces its own binary error.

Note that String.format("%.2f", 2.675) produces "2.68": Java's formatter rounds based on the shortest decimal form of the double (2.675), not its exact binary value. BigDecimal.valueOf(2.675).setScale(2, RoundingMode.HALF_UP) gives the same result explicitly. When rounding rules are part of a business requirement, use BigDecimal from the start.

Parsing and Converting

double a = Double.parseDouble("1499.99");
Double b = Double.valueOf("  3.5 ");            // leading/trailing whitespace is allowed
double c = Double.parseDouble("1e-3");          // 0.001
double nan = Double.parseDouble("NaN");         // NaN
double d = Double.parseDouble("1,234.5".replace(",", ""));   // grouping separators must be removed

Unlike Integer.parseInt, parseDouble ignores surrounding whitespace. It does not accept locale-specific formats such as 1.234,5; use NumberFormat for those. Invalid text throws NumberFormatException.

Comparing doubles

Exact comparison with == is fragile after arithmetic. A robust check combines a relative tolerance (for large values) with an absolute tolerance (for values near zero):

static boolean approxEqual(double a, double b, double relTol, double absTol) {
    double diff = Math.abs(a - b);
    return diff <= absTol || diff <= relTol * Math.max(Math.abs(a), Math.abs(b));
}

approxEqual(0.1 + 0.2, 0.3, 1e-9, 1e-12);      // true
approxEqual(1e20 + 1e5, 1e20, 1e-9, 1e-12);    // true: a difference of 1e5 is tiny relative to 1e20
approxEqual(0.001, 0.002, 1e-9, 1e-12);        // false

A fixed absolute tolerance such as 1e-9 alone fails for large numbers (where neighboring doubles are far more than 1e-9 apart) and can be too loose for very small ones. Testing frameworks provide similar helpers, such as JUnit's assertEquals(expected, actual, delta).

double Versus BigDecimal

doubleBigDecimal
RepresentationBinary approximationExact decimal digits
SpeedHardware arithmetic, very fastSoftware arithmetic, much slower
Memory8 bytesAn object with an internal integer and scale
RoundingImplicit after every operationExplicit, with a chosen RoundingMode
Good forScience, statistics, graphics, measurementsMoney, tax, invoices, accounting

Practical Example: Response-Time Statistics

A monitoring tool computes summary statistics for API response times and flags outliers.

public class Db {
    record Stats(double mean, double stdDev, double min, double max) { }

    static Stats stats(double[] xs) {
        double sum = 0, min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY;
        for (double x : xs) {
            sum += x;
            min = Math.min(min, x);
            max = Math.max(max, x);
        }
        double mean = sum / xs.length;
        double sq = 0;
        for (double x : xs) sq += (x - mean) * (x - mean);
        return new Stats(mean, Math.sqrt(sq / (xs.length - 1)), min, max);
    }

    public static void main(String[] args) {
        double[] responseMs = {120.5, 98.2, 143.0, 110.7, 101.3, 512.9, 118.4};
        Stats s = stats(responseMs);
        System.out.printf("mean=%.2f ms  sd=%.2f ms  min=%.1f  max=%.1f%n", s.mean(), s.stdDev(), s.min(), s.max());
        for (double x : responseMs) {
            double z = (x - s.mean()) / s.stdDev();
            if (Math.abs(z) > 2) System.out.printf("Outlier: %.1f ms (z = %.2f)%n", x, z);
        }
        System.out.println(Double.isNaN(stats(new double[0]).mean()));
    }
}

Output:

mean=172.14 ms  sd=150.99 ms  min=98.2  max=512.9
Outlier: 512.9 ms (z = 2.26)
true

This is exactly the kind of work double is designed for: averages, standard deviations, and ratios where tiny binary rounding errors are irrelevant to the result. Several details are worth noting:

  • Starting values for min and max. min and max start at POSITIVE_INFINITY and NEGATIVE_INFINITY, so the first real value always replaces them.
  • Sample standard deviation. It divides by n - 1, and the z-score expresses how many standard deviations each reading lies from the mean. The single slow request at 512.9 ms stands out.
  • Empty input. The last line shows a pitfall. Passing an empty array divides 0.0 by 0 and returns NaN instead of throwing, so production code should check the length first or validate the result with Double.isFinite.

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 Double Class and get answers drawn from it.

Signed-in readers only.