You have used java.math.BigDecimal.BigDecimal(double val) constructor.

From JavaDoc:

java.math.BigDecimal.BigDecimal(double val)


Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer. 

Notes: 
1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. 
2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one. 
3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method. 

Here First point suggests that :

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

Second point suggests to use the constructor with string argument for exact value.

This is the reason for difference of value.

Answer from Raj on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › java numbers › bigdecimal and biginteger in java
BigDecimal and BigInteger in Java | Baeldung
December 16, 2024 - It consists of two parts: Unscaled ... digits are to the right of the decimal point · For example, the BigDecimal 3.14 has an unscaled value of 314 and a scale of 2....
🌐
GeeksforGeeks
geeksforgeeks.org › java › bigdecimal-class-java
BigDecimal Class in Java - GeeksforGeeks
March 8, 2024 - ... // Java Program to illustrate ... args) { // Create two new BigDecimals BigDecimal bd1 = new BigDecimal("124567890.0987654321"); BigDecimal bd2 = new BigDecimal("987654321.123456789"); // Addition of two...
🌐
CodeGym
codegym.cc › java blog › java numbers › bigdecimal in java
BigDecimal in Java
January 15, 2025 - The Long data type has a quite large range of possible values, but it is still limited to 64 bits. What do we need to come up with if our Very Large Number requires 100 bits? Fortunately, we don't need to invent anything. For cases such as this, Java has two special classes: BigInteger (for integers) and BigDecimal (for floating-point numbers).
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › math › BigDecimal.html
BigDecimal (Java Platform SE 8 )
April 21, 2026 - The results of this constructor ... equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625....
🌐
Codementor
codementor.io › community › bigdecimal class in java
BigDecimal Class in Java | Codementor
June 23, 2024 - MathContext mc = new MathContext(3); BigDecimal bigDecimal = new BigDecimal("0.1", mc); System.out.println(bigDecimal); ... As a result, the displayed value has 2 digits after the decimal symbol.
🌐
Medium
medium.com › @medcherrou › mastering-bigdecimal-in-java-handling-precision-and-rounding-challenges-88a7503fb461
Mastering BigDecimal in Java: Handling Precision and Rounding Challenges | by Med Cherrou | Medium
December 10, 2024 - Have you ever struggled with precision issues in Java, especially in financial applications? Handling money, scientific calculations, or any scenario requiring high precision can quickly become problematic when using double or float. The BigDecimal class is here to save the day!
Find elsewhere
🌐
Piotr Horzycki
peterdev.pl › all-you-need-to-know-about-javas-bigdecimal
All you need to know about Java’s BigDecimal
February 11, 2021 - The BigDecimal class uses rules defined by a MathContext to perform numerical operations. In most cases you won’t need to worry about it. However, we should get back to the example of dividing 1 by 3.
🌐
Scaler
scaler.com › home › topics › bigdecimal java
BigDecimal Java - Scaler Topics
May 4, 2023 - In contrast to fixed point numbers, floating point numbers typically return a result with a little error (about 10-19). This is the reason why, in the example above, the outcome of 0.04-0.03 is 0.009999999999999998.
🌐
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.

Top answer
1 of 3
3

You have used java.math.BigDecimal.BigDecimal(double val) constructor.

From JavaDoc:

java.math.BigDecimal.BigDecimal(double val)


Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer. 

Notes: 
1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. 
2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one. 
3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method. 

Here First point suggests that :

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

Second point suggests to use the constructor with string argument for exact value.

This is the reason for difference of value.

2 of 3
0

You are trying to use a literal number that cannot fit in a double which has a maximum of 15 decimals precision - probably why you want to use BigDecimal in the first place. So your number is converted to the most acurate representation in a double before initialising BigDecimal. Then the BigDecimal contructor compounds the error by messing up the already messed up double.

You will have to represent numbers as Strings to get that precision.

    double x = 2300000870000000000067.7797d;
    System.out.println("double:"+x);        
    BigDecimal balance = new BigDecimal(2300000870000000000067.7797);
    System.out.println("balance:"+balance);
    BigDecimal stringbased = new BigDecimal("2300000870000000000067.7797");
    System.out.println("stringbased:"+stringbased);

Prints

double:2.30000087E21
balance:2300000869999999975424
stringbased:2300000870000000000067.7797
🌐
Baeldung
baeldung.com › home › java › java numbers › java double vs. bigdecimal
Java Double vs. BigDecimal | Baeldung
January 8, 2024 - Compare Java's Double to BigDecimal and learn about their differences.
🌐
Dummies
dummies.com › article › technology › programming-web-design › java › how-to-create-bigdecimal-objects-in-java-153270
How to Create BigDecimal Objects in Java | dummies
March 26, 2016 - Note: The BigDecimal class has ... have a BigDecimal object without a value. No items found. Doug Lowe is the information technology director at Blair, Church & Flynn Consulting Engineers, a civil engineering firm. He has written more than 50 For Dummies books on topics ranging from Java to electronics ...
Author  
🌐
GeeksforGeeks
geeksforgeeks.org › java › bigdecimal-add-method-in-java-with-examples
BigDecimal add() Method in Java with Examples - GeeksforGeeks
July 11, 2025 - ... // Java program to demonstrate ... of String created // Holds the values to calculate the sum String input1 = "545456468445645468464645"; String input2 = "425645...
🌐
Coderanch
coderanch.com › t › 371093 › java › Rounding-BigDecimal
Rounding using BigDecimal (Java in General forum at Coderanch)
Your BigDecimal actually has a value of 93.974999999999999431586...etc. (use instead of bd.doubleValue() to see this result. As such, 93.97 is closer than 93.98; they are not equidistant. As pointed out in the oter thread, this will work fine if you create you BigDecimal using or even (for ...
Top answer
1 of 5
214

Those are two separate questions: "What should I use for BigDecimal?" and "What do I do in general?"

For BigDecimal: this is a bit tricky, because they don't do the same thing. BigDecimal.valueOf(double) will use the canonical String representation of the double value passed in to instantiate the BigDecimal object. In other words: The value of the BigDecimal object will be what you see when you do System.out.println(d).

If you use new BigDecimal(d) however, then the BigDecimal will try to represent the double value as accurately as possible. This will usually result in a lot more digits being stored than you want. Strictly speaking, it's more correct than valueOf(), but it's a lot less intuitive.

There's a nice explanation of this in the JavaDoc:

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

In general, if the result is the same (i.e. not in the case of BigDecimal, but in most other cases), then valueOf() should be preferred: it can do caching of common values (as seen on Integer.valueOf()) and it can even change the caching behaviour without the caller having to be changed. new will always instantiate a new value, even if not necessary (best example: new Boolean(true) vs. Boolean.valueOf(true)).

2 of 5
64

If you are using your BigDecimal objects to store currency values, then I strongly recommend that you do NOT involve any double values anywhere in their calculations.

As stated in another answer, there are known accuracy issues with double values and these will come back to haunt you big time.

Once you get past that, the answer to your question is simple. Always use the constructor method with the String value as the argument to the constructor, as there is no valueOf method for String.

If you want proof, try the following:

BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);

You'll get the following output:

bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01

See also this related question

🌐
W3Resource
w3resource.com › java-tutorial › java-big-decimal-class.php
Java BigDecimal Class - w3resource
August 19, 2022 - The compareTo method works as follows: ... BigDecimalCompare { public static void main(String[]args){ BigDecimal a = new BigDecimal("31234"); BigDecimal b = new BigDecimal("31234....
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › math › BigDecimal.html
BigDecimal (Java SE 17 & JDK 17)
April 21, 2026 - The results of this constructor ... equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625....
🌐
Medium
solutionsarchitecture.medium.com › mastering-big-decimals-in-java-understanding-implementation-performance-and-alternatives-7e3a3a96efc6
Mastering Big Decimals in Java: Understanding Implementation, Performance, and Alternatives | by Rahul Krishnan | Medium
September 22, 2024 - How does it work?BigDecimal is implemented using a combination of integer arithmetic and scaling. The number is represented as an integer and a scale, which determines the number of digits to the right of the decimal point. Arithmetic operations on BigDecimal objects are performed using integer arithmetic, and the scale is adjusted accordingly.
🌐
W3Schools
w3schools.com › java › java_data_types_numbers.asp
Java Numbers
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP W3.CSS C C++ C# HOW TO BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING INTRO TO HTML & CSS BASH RUST TOOLS ... Variables Print Variables Multiple Variables Identifiers Constants (Final) Real-Life Examples Code Challenge Java Data Types