@PeterLawrey states max precision in 15.

That's actually not what he stated at all. What he stated was:

double has 15 decimal places of accuracy

and he is wrong. They have 15 decimal digits of accuracy.

The number of decimal digits in any number is given by its log to the base 10. 15 is the floor value of log10(253-1), where 53 is the number of bits of mantissa (including the implied bit), as described in the Javadoc and IEEE 754, and 253-1 is therefore the maximum possible mantissa value. The actual value is 15.954589770191003298111788092734 to the limits of the Windows calculator.

He is quite wrong to describe it as 'decimal places of accuracy'. A double has 15 decimal digits of accuracy if they are all before the decimal point. For numbers with fractional parts you can get many more than 15 digits in the decimal representation, because of the incommensurability of decimal and binary fractions.

Answer from user207421 on Stack Overflow
Top answer
1 of 4
14

@PeterLawrey states max precision in 15.

That's actually not what he stated at all. What he stated was:

double has 15 decimal places of accuracy

and he is wrong. They have 15 decimal digits of accuracy.

The number of decimal digits in any number is given by its log to the base 10. 15 is the floor value of log10(253-1), where 53 is the number of bits of mantissa (including the implied bit), as described in the Javadoc and IEEE 754, and 253-1 is therefore the maximum possible mantissa value. The actual value is 15.954589770191003298111788092734 to the limits of the Windows calculator.

He is quite wrong to describe it as 'decimal places of accuracy'. A double has 15 decimal digits of accuracy if they are all before the decimal point. For numbers with fractional parts you can get many more than 15 digits in the decimal representation, because of the incommensurability of decimal and binary fractions.

2 of 4
2

Run this code, and see where it stops

public class FindPrecisionDouble {
  static public void main(String[] args) {
    double x = 1.0;
    double y = 0.5;
    double epsilon = 0;
    int nb_iter = 0;
    while ((nb_iter < 1000) && (x != y)) {
        System.out.println(x-y);
        epsilon = Math.abs(x-y);
        y = ( x + y ) * 0.5;
    }
    final double prec_decimal = - Math.log(epsilon) / Math.log(10.0);
    final double prec_binary = - Math.log(epsilon) / Math.log(2.0);
    System.out.print("On this machine, for the 'double' type, ");
    System.out.print("epsilon = " );
    System.out.println( epsilon );
    System.out.print("The decimal precision is " );
    System.out.print( prec_decimal );
    System.out.println(" digits" );
    System.out.print("The binary precision is " );
    System.out.print( prec_binary );
    System.out.println(" bits" );
  }
}

Variable y becomes the smallest value different than 1.0. On my computer (Mac Intel Core i5), it stops at 1.1102...E-16. It then prints the precision (in decimal and in binary).

As stated in https://en.wikipedia.org/wiki/Machine_epsilon, floating-point precision can be estimated with the epsilon value. It is "the smallest number that, when added to one, yields a result different from one" (I did a small variation: 1-e instead of 1+e, but the logic is the same)

I'll explain in decimal: if you have a 4-decimals precision, you can express 1.0000 - 0.0001, but you cannot express the number 1.00000-0.00001 (you lack the 5th decimal). In this example, with a 4-decimals precision, the epsilon is 0.0001. The epsilon directly measures the floating-point precision. Just transpose to binary.

Edit Your question asked "How to determine...". The answer you were searching were more an explanation of than a way to determine precision (with the answer you accepted). Anyways, for other people, running this code on a machine will determine the precision for the "double" type.

🌐
Oracle
docs.oracle.com › javadb › 10.10.1.2 › ref › rrefsqljdoubleprecision.html
DOUBLE PRECISION data type
DOUBLE can be used synonymously with DOUBLE PRECISION. ... These limits are the same as the java.lang.Double Java type limits.
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-set-precision-for-double-values-in-java
How to Set Precision For Double Values in Java? - GeeksforGeeks
July 12, 2025 - From the above output, it is clear that precision of 20 digits is been carried out for the first entry whereas precision to 5 digits is carried out on input double value. ... // Demonstrating the precision modifier import java.util.*; class ...
🌐
TheServerSide
theserverside.com › blog › Coffee-Talk-Java-News-Stories-and-Opinions › Java-double-precision-2-decimal-places-example-float-range-math-jvm
Java double decimal precision
The precision of a double in Java is 10-324 decimal places, although true mathematical precision can suffer due to issues with binary arithmetic.
🌐
Apache
db.apache.org › derby › docs › 10.1 › ref › rrefsqljdoubleprecision.html
DOUBLE PRECISION
DOUBLE can be used synonymously with DOUBLE PRECISION. ... These limits are different from the java.lang.DoubleJava type limits.
🌐
TheServerSide
theserverside.com › blog › Coffee-Talk-Java-News-Stories-and-Opinions › Float-vs-Double-Whats-the-difference
Java double vs float: What's the difference?
In Java, the Float and Double wrapper classes have two properties that return the upper and lower limits of float and double data types, MIN_VALUE and MAX_VALUE:
🌐
Baeldung
baeldung.com › home › java › java numbers › double precision issue in java
Double Precision Issue in Java | Baeldung
January 8, 2024 - According to the standard, the ... number (11 bits) Fraction (Mantissa) – contains the significant digits of the number (52 bits) Now, to understand the double precision issue, let’s perform a simple addition of two decimal ...
Find elsewhere
🌐
Coderanch
coderanch.com › t › 681508 › java › maximum-decimal-places-float-double
The maximum decimal places for a float and a double: Where are they exactly defined? (Beginning Java forum at Coderanch)
So I am not an expert, but basically, java uses the IEEE standard for floating point numbers. that means what it really does is store the number in two parts the "number" part, and the "exponent" part. think of scientific notation: 4.232 x 10^3. if everyone always agrees that the base for the ...
🌐
Coderanch
coderanch.com › t › 670713 › java › Double-MAX
What is Double.MAX_VALUE + 1? [Solved] (Java in General forum at Coderanch)
I believe all double operations return a real double value, one which closest approximates what the value would be if you had near infinite precision. That means that no matter how small value2 becomes, as long as both operands are positive, you well never get POSITIVE_INFINITY, because MAX_VALUE ...
🌐
Coderanch
coderanch.com › t › 509676 › java › Precision-scale-decimal
Precision and scale of a decimal value (Java in General forum at Coderanch)
In java decimal means a double value for a precision of 1 , and a scale of 7 , I am checking it this way : The max value of a double with precision 1 and scale 7 is 9.9999999, the reason I am doing this is anything above this precision and scale it should allow, but if it is below precision ...
Top answer
1 of 16
183

As others have mentioned, you'll probably want to use the BigDecimal class, if you want to have an exact representation of 11.4.

Now, a little explanation into why this is happening:

The float and double primitive types in Java are floating point numbers, where the number is stored as a binary representation of a fraction and a exponent.

More specifically, a double-precision floating point value such as the double type is a 64-bit value, where:

  • 1 bit denotes the sign (positive or negative).
  • 11 bits for the exponent.
  • 52 bits for the significant digits (the fractional part as a binary).

These parts are combined to produce a double representation of a value.

(Source: Wikipedia: Double precision)

For a detailed description of how floating point values are handled in Java, see the Section 4.2.3: Floating-Point Types, Formats, and Values of the Java Language Specification.

The byte, char, int, long types are fixed-point numbers, which are exact representions of numbers. Unlike fixed point numbers, floating point numbers will some times (safe to assume "most of the time") not be able to return an exact representation of a number. This is the reason why you end up with 11.399999999999 as the result of 5.6 + 5.8.

When requiring a value that is exact, such as 1.5 or 150.1005, you'll want to use one of the fixed-point types, which will be able to represent the number exactly.

As has been mentioned several times already, Java has a BigDecimal class which will handle very large numbers and very small numbers.

From the Java API Reference for the BigDecimal class:

Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. The value of the number represented by the BigDecimal is therefore (unscaledValue × 10^-scale).

There has been many questions on Stack Overflow relating to the matter of floating point numbers and its precision. Here is a list of related questions that may be of interest:

  • Why do I see a double variable initialized to some value like 21.4 as 21.399999618530273?
  • How to print really big numbers in C++
  • How is floating point stored? When does it matter?
  • Use float or decimal for accounting application dollar amount?

If you really want to get down to the nitty gritty details of floating point numbers, take a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic.

2 of 16
111

When you input a double number, for example, 33.33333333333333, the value you get is actually the closest representable double-precision value, which is exactly:

33.3333333333333285963817615993320941925048828125

Dividing that by 100 gives:

0.333333333333333285963817615993320941925048828125

which also isn't representable as a double-precision number, so again it is rounded to the nearest representable value, which is exactly:

0.3333333333333332593184650249895639717578887939453125

When you print this value out, it gets rounded yet again to 17 decimal digits, giving:

0.33333333333333326
🌐
The Floating-Point Guide
floating-point-gui.de › languages › java
The Floating-Point Guide - Floating-point cheat sheet for Java
float f = 0.1f; // 32 bit float, note f suffix double d = 0.1d; // 64 bit float, suffix optional · The strictfp keyword on classes, interfaces and methods forces all intermediate results of floating-point calculations to be IEEE 754 values as well, guaranteeing identical results on all platforms. Without that keyword, implementations can use an extended exponent range where available, resulting in more precise results and faster execution on many common CPUs. Java has an arbitrary-precision decimal type named java.math.BigDecimal, which also allows to choose the rounding mode.
🌐
Oracle
docs.oracle.com › en › java › javase › 21 › docs › api › › java.base › java › lang › Double.html
Double (Java SE 21 & JDK 21)
January 20, 2026 - Otherwise, s is regarded as representing an exact decimal value in the usual "computerized scientific notation" or as an exact hexadecimal value; this exact numerical value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type double by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic, which includes preserving the sign of a zero value. Note that the round-to-nearest rule also implies overflow and underflow behaviour; if the exact value of s is large enough in magnitude (greater than or equal to (MAX_VALUE + ulp(MAX_VALUE)/2), rounding to double will result in an infinity and if the exact value of s is small enough in magnitude (less than or equal to MIN_VALUE/2), rounding to float will result in a zero.
🌐
Hipparchus
hipparchus.org › hipparchus-coverage › jacoco-aggregate › hipparchus-core › org.hipparchus.util › Precision.java.html
Precision.java
* * @param x first value * @param y second value * @param maxUlps {@code (maxUlps - 1)} is the number of floating point * values between {@code x} and {@code y}. * @return <ul><li>0 if {@link #equals(double, double, int) equals(x, y, maxUlps)}</li> * <li>&lt; 0 if !{@link #equals(double, double, int) equals(x, y, maxUlps)} &amp;&amp; x &lt; y</li> * <li>&gt; 0 if !{@link #equals(double, double, int) equals(x, y, maxUlps)} &amp;&amp; x &gt; y * or either argument is NaN</li></ul> */ public static int compareTo(final double x, final double y, final int maxUlps) { if (equals(x, y, maxUlps)) { return 0; } else if (x < y) { return -1; } return 1; } /** * Returns true iff they are equal as defined by * {@link #equals(float,float,int) equals(x, y, 1)}. * * @param x first value * @param y second value * @return {@code true} if the values are equal.
🌐
Wikipedia
en.wikipedia.org › wiki › Double-precision_floating-point_format
Double-precision floating-point format - Wikipedia
January 9, 2026 - Most implementations provide SINGLE-FLOATs and DOUBLE-FLOATs with the other types appropriate synonyms. Common Lisp provides exceptions for catching floating-point underflows and overflows, and the inexact floating-point exception, as per IEEE 754. No infinities and NaNs are described in the ANSI standard, however, several implementations do provide these as extensions. On Java before version 1.2, every implementation had to be IEEE 754 compliant.
🌐
Oracle
docs.oracle.com › en › java › javase › 24 › docs › api › java.base › java › lang › Double.html
Double (Java SE 24 & JDK 24)
July 15, 2025 - Otherwise, s is regarded as representing an exact decimal value in the usual "computerized scientific notation" or as an exact hexadecimal value; this exact numerical value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type double by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic, which includes preserving the sign of a zero value. Note that the round-to-nearest rule also implies overflow and underflow behaviour; if the exact value of s is large enough in magnitude (greater than or equal to (MAX_VALUE + ulp(MAX_VALUE)/2), rounding to double will result in an infinity and if the exact value of s is small enough in magnitude (less than or equal to MIN_VALUE/2), rounding to float will result in a zero.
🌐
Apache Commons
commons.apache.org › proper › commons-math › javadocs › api-3.6.1 › org › apache › commons › math3 › util › Precision.html
Precision (Apache Commons Math 3.6.1 API)
... Returns true if the arguments are both NaN, are equal or are within the range of allowed error (inclusive). ... Returns true if the arguments are equal or within the range of allowed error (inclusive). Two float numbers are considered equal if there are (maxUlps - 1) (or fewer) floating ...