A BigDecimal is an exact way of representing numbers. A Double has a certain precision. Working with doubles of various magnitudes (say d1=1000.0 and d2=0.001) could result in the 0.001 being dropped altogether when summing as the difference in magnitude is so large. With BigDecimal this would not happen.

The disadvantage of BigDecimal is that it's slower, and it's a bit more difficult to program algorithms that way (due to + - * and / not being overloaded).

If you are dealing with money, or precision is a must, use BigDecimal. Otherwise Doubles tend to be good enough.

I do recommend reading the javadoc of BigDecimal as they do explain things better than I do here :)

Answer from extraneon on Stack Overflow
🌐
Medium
medium.com β€Ί @qingedaig β€Ί java-bigdecimal-vs-double-vs-float-012c7149e550
Java BigDecimal vs double vs float | by Alice Dai | Medium
October 15, 2024 - Avoiding Floating-Point Errors: ... totalPrice); } } Performance: Use double for general-purpose floating-point arithmetic where performance is a consideration and exact precision is not critical....
🌐
Coderanch
coderanch.com β€Ί t β€Ί 492688 β€Ί java β€Ί java-math-BigDecimal-double-float
java.math.BigDecimal vs double or float datatypes (Beginning Java forum at Coderanch)
April 22, 2010 - Well, first of all: float and double are two primitive types, BigDecimal is a class. It doesn't just represent numbers but operations too. A float is a decimal numeric type represented with 32 bit. A double is a 64 bit decimal number, so it can represent larger values than a float.
Discussions

java - Double vs. BigDecimal? - Stack Overflow
BigDecimal is part of the Java language and is useful for a variety of applications ranging from the financial to the scientific (that's where sort of am). There's nothing wrong with using doubles for certain calculations. Suppose, however, you wanted to calculate Math.Pi * Math.Pi / 6, that is, the value of the Riemann Zeta Function for a real argument of two (a project I'm currently working on). Floating... More on stackoverflow.com
🌐 stackoverflow.com
floating point - Java:Why should we use BigDecimal instead of Double in the real world? - Stack Overflow
When dealing with real world monetary values, I am advised to use BigDecimal instead of Double.But I have not got a convincing explanation except, "It is normally done that way". Can you please th... More on stackoverflow.com
🌐 stackoverflow.com
Double vs BigDecimal in financial programming

Use long or big decimal. Performance problems will most probably arise elsewhere before you factor a big decimal as the culprit

More on reddit.com
🌐 r/java
105
44
May 22, 2018
floating point - Java big decimal or double - Stack Overflow
I have a number in the format of (13,2) 13 digits and 2 decimal places. I need to do some calculation on it (like multiplication, division). I am planning to use BigDecimal for the calculations. Shall i use double or float for the calculation as BigDecimal is bit on slower side? More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 6
54

I think this describes solution to your problem: Java Traps: Big Decimal and the problem with double here

From the original blog which appears to be down now.

Java Traps: double

Many traps lay before the apprentice programmer as he walks the path of software development. This article illustrates, through a series of practical examples, the main traps of using Java's simple types double and float. Note, however, that to fully embrace precision in numerical calculations you a text book (or two) on the topic is required. Consequently, we can only scratch the surface of the topic. That being said, the knowledge conveyed here, should give you the fundamental knowledge required to spot or identify bugs in your code. It is knowledge I think any professional software developer should be aware of.

  1. Decimal numbers are approximations

    While all natural numbers between 0 - 255 can be precisely described using 8 bit, describing all real numbers between 0.0 - 255.0 requires an infinitely number of bits. Firstly, there exists infinitely many numbers to describe in that range (even in the range 0.0 - 0.1), and secondly, certain irrational numbers cannot be described numerically at all. For example e and Ο€. In other words, the numbers 2 and 0.2 are vastly differently represented in the computer.

    Integers are represented by bits representing values 2n where n is the position of the bit. Thus the value 6 is represented as 23 * 0 + 22 * 1 + 21 * 1 + 20 * 0 corresponding to the bit sequence 0110. Decimals, on the other hand, are described by bits representing 2-n, that is the fractions 1/2, 1/4, 1/8,... The number 0.75 corresponds to 2-1 * 1 + 2-2 * 1 + 2-3 * 0 + 2-4 * 0 yielding the bits sequence 1100 (1/2 + 1/4).

    Equipped with this knowledge, we can formulate the following rule of thumb: Any decimal number is represented by an approximated value.

    Let us investigate the practical consequences of this by performing a series of trivial multiplications.

    System.out.println( 0.2 + 0.2 + 0.2 + 0.2 + 0.2 );
    1.0
    

    1.0 is printed. While this is indeed correct, it may give us a false sense of security. Coincidentally, 0.2 is one of the few values Java is able to represent correctly. Let's challenge Java again with another trivial arithmetical problem, adding the number 0.1 ten times.

    System.out.println( 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f );
    System.out.println( 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d );
    
    1.0000001
    0.9999999999999999
    

    According to slides from Joseph D. Darcy's blog the sums of the two calculations are 0.100000001490116119384765625 and 0.1000000000000000055511151231... respectively. These results are correct for a limited set of digits. float's have a precision of 8 leading digits, while double has 17 leading digits precision. Now, if the conceptual mismatch between the expected result 1.0 and the results printed on the screens were not enough to get your alarm bells going, then notice how the numbers from mr. Darcy's slides does not seem to correspond to the printed numbers! That's another trap. More on this further down.

    Having been made aware of mis-calculations in seemingly the simples possible scenarios, it is reasonable to contemplate on just how quickly the impression may kick in. Let us simplify the problem to adding only three numbers.

    System.out.println( 0.3 == 0.1d + 0.1d + 0.1d );
    false
    

    Shockingly, the imprecision already kicks in at three additions!

  2. Doubles overflow

    As with any other simple type in Java, a double is represented by a finite set of bits. Consequently, adding a value or multiplying a double can yield surprising results. Admitedly, numbers have to be pretty big in order to overflow, but it happens. Let's try multiplying and then dividing a big number. Mathematical intuition says that the result is the original number. In Java we may get a different result.

    double big = 1.0e307 * 2000 / 2000;
    System.out.println( big == 1.0e307 );
    false
    

    The problem here is that big is first multiplied, overflowing, and then the overflowed number is divided. Worse, no exception or other kinds of warnings are raised to the programmer. Basically, this renders the expression x * y completely unreliable as no indication or guarantee is made in the general case for all double values represented by x, y.

  3. Large and small are not friends!

    Laurel and Hardy were often disagreeing about a lot of things. Similarly in computing, large and small are not friends. A consequence of using a fixed number of bits to represent numbers is that operating on really large and really small numbers in the same calculations will not work as expected. Let's try adding something small to something large.

    System.out.println( 1234.0d + 1.0e-13d == 1234.0d );
    true
    

    The addition has no effect! This contradicts any (sane) mathematical intuition of addition, which says that given two numbers positive numbers d and f, then d + f > d.

  4. Decimal numbers cannot be directly compared

    What we have learned so far, is that we must throw away all intuition we have gained in math class and programming with integers. Use decimal numbers cautiously. For example, the statement for(double d = 0.1; d != 0.3; d += 0.1) is in effect a disguised never ending loop! The mistake is to compare decimal numbers directly with each other. You should adhere to the following guide lines.

    Avoid equality tests between two decimal numbers. Refrain from if(a == b) {..}, use if(Math.abs(a-b) < tolerance) {..} where tolerance could be a constant defined as e.g. public static final double tolerance = 0.01 Consider as an alternative to use the operators <, > as they may more naturally describe what you want to express. For example, I prefer the form for(double d = 0; d <= 10.0; d+= 0.1) over the more clumsy for(double d = 0; Math.abs(10.0-d) < tolerance; d+= 0.1) Both forms have their merits depending on the situation though: When unit testing, I prefer to express that assertEquals(2.5, d, tolerance) over saying assertTrue(d > 2.5) not only does the first form read better, it is often the check you want to be doing (i.e. that d is not too large).

  5. WYSINWYG - What You See Is Not What You Get

    WYSIWYG is an expression typically used in graphical user interface applications. It means, "What You See Is What You Get", and is used in computing to describe a system in which content displayed during editing appears very similar to the final output, which might be a printed document, a web page, etc. The phrase was originally a popular catch phrase originated by Flip Wilson's drag persona "Geraldine", who would often say "What you see is what you get" to excuse her quirky behavior (from wikipedia).

    Another serious trap programmers often fall into, is thinking that decimal numbers are WYSIWYG. It is imperative to realize, that when printing or writing a decimal number, it is not the approximated value that gets printed/written. Phrased differently, Java is doing a lot of approximations behind the scenes, and persistently tries to shield you from ever knowing it. There is just one problem. You need to know about these approximations, otherwise you may face all sorts of mysterious bugs in your code.

    With a bit of ingenuity, however, we can investigate what really goes on behind the scene. By now we know that the number 0.1 is represented with some approximation.

    System.out.println( 0.1d );
    0.1
    

    We know 0.1 is not 0.1, yet 0.1 is printed on the screen. Conclusion: Java is WYSINWYG!

    For the sake of variety, let's pick another innocent looking number, say 2.3. Like 0.1, 2.3 is an approximated value. Unsurprisingly when printing the number Java hides the approximation.

    System.out.println( 2.3d );
    2.3
    

    To investigate what the internal approximated value of 2.3 may be, we can compare the number to other numbers in a close range.

    double d1 = 2.2999999999999996d;
    double d2 = 2.2999999999999997d;
    System.out.println( d1 + " " + (2.3d == d1) );
    System.out.println( d2 + " " + (2.3d == d2) );
    2.2999999999999994 false
    2.3 true
    

    So 2.2999999999999997 is just as much 2.3 as the value 2.3! Also notice that due to the approximation, the pivoting point is at ..99997 and not ..99995 where you ordinarily round round up in math. Another way to get to grips with the approximated value is to call upon the services of BigDecimal.

    System.out.println( new BigDecimal(2.3d) );
    2.29999999999999982236431605997495353221893310546875
    

    Now, don't rest on your laurels thinking you can just jump ship and only use BigDecimal. BigDecimal has its own collection of traps documented here.

    Nothing is easy, and rarely anything comes for free. And "naturally", floats and doubles yield different results when printed/written.

    System.out.println( Float.toString(0.1f) );
    System.out.println( Double.toString(0.1f) );
    System.out.println( Double.toString(0.1d) );
    0.1
    0.10000000149011612
    0.1
    

    According to the slides from Joseph D. Darcy's blog a float approximation has 24 significant bits while a double approximation has 53 significant bits. The morale is that In order to preserve values, you must read and write decimal numbers in the same format.

  6. Division by 0

    Many developers know from experience that dividing a number by zero yields abrupt termination of their applications. A similar behaviour is found is Java when operating on int's, but quite surprisingly, not when operating on double's. Any number, with the exception of zero, divided by zero yields respectively ∞ or -∞. Dividing zero with zero results in the special NaN, the Not a Number value.

    System.out.println(22.0 / 0.0);
    System.out.println(-13.0 / 0.0);
    System.out.println(0.0 / 0.0);
    Infinity
    -Infinity
    NaN
    

    Dividing a positive number with a negative number yields a negative result, while dividing a negative number with a negative number yields a positive result. Since division by zero is possible, you'll get different result depending on whether you divide a number with 0.0 or -0.0. Yes, it's true! Java has a negative zero! Don't be fooled though, the two zero values are equal as shown below.

    System.out.println(22.0 / 0.0);
    System.out.println(22.0 / -0.0);
    System.out.println(0.0 == -0.0);
    Infinity
    -Infinity
    true
    
  7. Infinity is weird

    In the world of mathematics, infinity was a concept I found hard to grasp. For example, I never acquired an intuition for when one infinity were infinitely larger than another. Surely Z > N, the set of all rational numbers is infinitely larger than the set of natural numbers, but that was about the limit of my intuition in this regard!

    Fortunately, infinity in Java is about as unpredictable as infinity in the mathematical world. You can perform the usual suspects (+, -, *, / on an infinite value, but you cannot apply an infinity to an infinity.

    double infinity = 1.0 / 0.0;
    System.out.println(infinity + 1);
    System.out.println(infinity / 1e300);
    System.out.println(infinity / infinity);
    System.out.println(infinity - infinity);
    Infinity
    Infinity
    NaN
    NaN
    

    The main problem here is that the NaN value is returned without any warnings. Hence, should you foolishly investigate whether a particular double is even or odd, you can really get into a hairy situation. Maybe a run-time exception would have been more appropriate?

    double d = 2.0, d2 = d - 2.0;
    System.out.println("even: " + (d % 2 == 0) + " odd: " + (d % 2 == 1));
    d = d / d2;
    System.out.println("even: " + (d % 2 == 0) + " odd: " + (d % 2 == 1));
    even: true odd: false
    even: false odd: false
    

    Suddenly, your variable is neither odd nor even! NaN is even weirder than Infinity An infinite value is different from the maximum value of a double and NaN is different again from the infinite value.

    double nan = 0.0 / 0.0, infinity = 1.0 / 0.0;
    System.out.println( Double.MAX_VALUE != infinity );
    System.out.println( Double.MAX_VALUE != nan );
    System.out.println( infinity         != nan );
    true
    true
    true
    

    Generally, when a double have acquired the value NaN any operation on it results in a NaN.

    System.out.println( nan + 1.0 );
    NaN
    
  8. Conclusions

    1. Decimal numbers are approximations, not the value you assign. Any intuition gained in math-world no longer applies. Expect a+b = a and a != a/3 + a/3 + a/3
    2. Avoid using the ==, compare against some tolerance or use the >= or <= operators
    3. Java is WYSINWYG! Never believe the value you print/write is approximated value, hence always read/write decimal numbers in the same format.
    4. Be careful not to overflow your double, not to get your double into a state of Β±Infinity or NaN. In either case, your calculations may be not turn out as you'd expect. You may find it a good idea to always check against those values before returning a value in your methods.
2 of 6
44

It's called loss of precision and is very noticeable when working with either very big numbers or very small numbers. The binary representation of decimal numbers with a radix is in many cases an approximation and not an absolute value. To understand why you need to read up on floating number representation in binary. Here is a link: http://en.wikipedia.org/wiki/IEEE_754-2008. Here is a quick demonstration:
in bc (An arbitrary precision calculator language) with precision=10:

(1/3+1/12+1/8+1/15) = 0.6083333332
(1/3+1/12+1/8) = 0.541666666666666
(1/3+1/12) = 0.416666666666666

Java double:
0.6083333333333333
0.5416666666666666
0.41666666666666663

Java float:

0.60833335
0.5416667
0.4166667


If you are a bank and are responsible for thousands of transactions every day, even though they are not to and from one and same account (or maybe they are) you have to have reliable numbers. Binary floats are not reliable - not unless you understand how they work and their limitations.
🌐
LinkedIn
linkedin.com β€Ί pulse β€Ί why-we-should-use-bigdecimal-instead-double-java-financial-ismail
Why we should use BigDecimal instead double in java for financial systems
May 17, 2022 - Even though the difference between ... financial and business systems. ... Currently, BigDecimal class is the best solution to avoid the floating point errors during calculations....
🌐
Quora
quora.com β€Ί What-is-the-difference-between-BigDecimal-vs-Double
What is the difference between BigDecimal vs Double? - Quora
Answer (1 of 6): Double is a wrapper for the Java native double type, a 64-bit floating point number. BigDecimal is arbitrary-precision arithmetic. It can represent numbers to as many bits of precision as you want to throw memory and time at. (Technically, it's limited to a 32 bit exponent, but ...
Find elsewhere
🌐
Medium
medium.com β€Ί javarevisited β€Ί float-vs-double-vs-bigdecimal-understanding-precision-in-computer-arithmetic-3097df25d8cf
Float vs Double vs BigDecimal: Understanding Precision in Computer Arithmetic | by Suraj Pal | Javarevisited | Medium
June 18, 2025 - Float Structure (32 bits): β”Œβ”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚Sβ”‚EEEEEEEE β”‚MMMM MMMM MMMM MMMM MMMM MMM β”‚ β””β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 1 8 bits 23 bits Formula: (-1)^S Γ— (1 + M/2Β²Β³) Γ— 2^(E-127) ... Double Structure (64 bits): β”Œβ”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
🌐
Medium
medium.com β€Ί @reachansari β€Ί use-of-bigdecimal-instead-double-in-java-for-financial-systems-591440bdd5f4
Use of BigDecimal instead of double in Java for Financial systems | by Thameem Ansari | Medium
March 22, 2022 - As it is shown in BigDecimalStringConstructor we can use BigDecimal class to overcome the floating point errors. Like double has few disadvantages, BigDecimal class main disadvantage is it slower than double.
🌐
Reddit
reddit.com β€Ί r/java β€Ί double vs bigdecimal in financial programming
r/java on Reddit: Double vs BigDecimal in financial programming
May 22, 2018 -

Everyone says that BigDecimal should be used when dealing with money but it’s much slower and takes more memory than double. I would think this would be especially important in high frequency low-latency applications like trading. Do people actually use BigDecimal in such systems or do they use doubles with some kind of workaround to handle the precision issue?

Edit: I do have experience working on trading and risk systems and I see doubles used much more often than BigDecimal so I was curious to see if this is more common in actual practice. Most of the systems I worked on only need precision to the penny so I wonder if that’s the reason?

Also, BigDecimal is a pain to use and code written with it look much uglier than plain doubles.

🌐
Upgrad
upgrad.com β€Ί home β€Ί blog β€Ί software development β€Ί difference between float and double in java: float vs double in java, similarities, and more
Float vs Double in Java: Key Differences & Similarities
March 5, 2025 - Use the float keyword and append an 'f' or 'F' to the value, e.g., float num = 3.14f;. For financial calculations requiring high precision, BigDecimal is preferred over float or double.
🌐
Baeldung
baeldung.com β€Ί home β€Ί java β€Ί java numbers β€Ί java double vs. bigdecimal
Java Double vs. BigDecimal | Baeldung
January 8, 2024 - The BigDecimal class offers better precision than Double, as it can perform calculations with arbitrary-precision decimals, avoiding the rounding errors arising from Double’s binary representation.
Top answer
1 of 2
7

The most important consideration is not speed but correctness.

If your value is a sample of a continuous value, like a measurement of a real-world property like size, distance, weight, angle, etc., then an IEEE-754 double or float is probably a better choice. This is because in this case powers of ten are not necessarily "rounder" than other values (e.g. angular measurements in radians can be transcendental numbers but still "round").

If your value is a discrete value like a measurement of money, then double is incorrect and a floating-point decimal type like BigDecimal is correct. This is because, in this case, discrete increments are meaningful, and a value of "0.01" is "rounder" and more correct than a number like "0.009999999999999" or "0.010000000000000001".

2 of 2
0

The simplest, most natural representation for data with two decimal places is BigDecimal with scale factor 2. Start with that. In most cases it will be fast enough.

If, when measured, it really is a serious performance problem, there are two more options:

  1. Use long to represent the number of hundredths. For example, US currency can be represented exactly as a long number of cents. Be very careful to ensure variable names and comments make it clear where dollars are being used, and where cents are being used.
  2. Use double to represent the amount as a fraction. This avoids the dollars-vs-cents bookkeeping, at the expense of rounding issues. You may need to periodically correct the rounding by multiplying by 100, rounding to nearest integer, and dividing by 100 again
🌐
Educative
educative.io β€Ί blog β€Ί float-vs-double-in-java
Float vs. double in Java
March 10, 2026 - Use case guidance: Float is preferred in memory-constrained or latency-sensitive contexts like mobile apps, graphics, and audio processing, while double is better suited for financial calculations, scientific computing, and defense systems. Rounding errors and tolerance: Both types produce rounding errors due to binary fraction representation, so you should compare floating-point values using a tolerance (epsilon) rather than exact equality checks. BigDecimal for exact precision: When neither float nor double provides sufficient accuracy, such as in currency or ledger calculations, use BigDecimal to avoid binary representation issues entirely.
🌐
DZone
dzone.com β€Ί data engineering β€Ί data β€Ί why you should never use float and double for monetary calculations
Why You Should Never Use Float and Double for Monetary Calculations
August 21, 2018 - We should really avoid using the BigDecimal (double value) constructor, and instead, we should really prefer using the BigDecimal(String), because BigDecimal (0.1) results in (0.1000000000000000055511151231257827021181583404541015625) being ...
🌐
Simplexacode
simplexacode.ch β€Ί en β€Ί blog β€Ί 2018 β€Ί 07 β€Ί using-bigdecimal-as-an-accurate-replacement-for-floating-point-numbers
Using BigDecimal as an Accurate Replacement for Floating-Point Numbers – SimplexaCode
The latter is usually preferred to the former since doubles are much more precise than floats (15–17 digits compared to 6–9 digits). I am not aware of any performance gains using floats, because common CPU architectures are designed for full-scale doubles (or even more).
🌐
Blogger
epramono.blogspot.com β€Ί 2005 β€Ί 01 β€Ί double-vs-bigdecimal.html
a developer's perspective: double vs. BigDecimal
January 31, 2005 - Float (32 bit precision) is the least precise, while BigDecimal (arbitrary precision) is the most precise. As a programmer, you should periodically ask yourself, "How precise do I need to be?", and choose accordingly. In the example given, it shows double precision to be accurate up to +/- ...
🌐
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?
The key difference between a float and double in Java is that a double can represent much larger numbers than a float. Both data types represent numbers with decimals, but a float is 32 bits in size while a double is 64 bits.