Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

This question already has an answer here:

I am convert String value to double and next BigDecimal why result changed?

  public static void main(String[] args) {
    String sum = "49561500049999950";
    System.out.println("Result " + BigDecimal.valueOf(Double.valueOf(sum)));
    /*Result 49561500049999952*/

}
share|improve this question

marked as duplicate by Jiri Tousek, Joe, vikingsteve, fabian java yesterday

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2  
You known you can directly convert your string to a BigDecimal? new BigDecimal(String val) . See the Javadoc: docs.oracle.com/javase/7/docs/api/java/math/… – jhamon yesterday
5  
    
importance notice for me reason of this problem – Majid Bahrevar yesterday
    
As @jhamon already said: you can directly initialize your BigDecimal with a string. Since doubles are inaccurate, Never initialize a BigDecimal with a double. You use BigDecimal because you want the increased precision. You immediately throw that away again if you use a double to initialize it. – Rudy Velthuis 9 hours ago

49561500049999950 can't be represented exactly as a double. If you look at the result of Double.valueOf(sum), you will see:

4.9561500049999952E16

So it has already lost precision before you convert to a BigDecimal; obviously, you can't then recover that precision, since BigDecimal can't "know" that you actually meant to represent 4.9561500049999950E16.

The smallest positive integer which cannot be represented exactly in a double is 9007199254740993, as can be found here:

 9007199254740993  <-- Smallest not exactly representable.
49561500049999950  <-- Your value

So your value is about 5 times bigger than values which can be represented exactly.

Skip the double conversion step, construct the BigDecimal directly from the String:

System.out.println("Result " + new BigDecimal(sum));
share|improve this answer
1  
BigDeciaml doesn't has a valueOf(String)method. You have to use new BigDecimal(String) – jhamon yesterday
    
@jhamon fixed.. – Andy Turner yesterday
1  
You mean "the smallest positive integer that can't be represented exactly in a double is 9007199254740993". – David Wallace yesterday
    
@DavidWallace thanks, that's less awkward :) – Andy Turner yesterday

Because of how IEEE 754 floating-point arithmetic works, as explained in the documentation. Did you check the result of Double.valueOf(sum)? It is 4.9561500049999952E16, which is 49561500049999952 when converted to non-scientific notation. Double values are not precise, don't use them if you need precise results.

share|improve this answer

It is recommended to only use the String BigDecimal constructor.

public 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:

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. 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. 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.

Java API

share|improve this answer

I am not sure why the result is changed but i have a solution for you. You can use BigDecimal constructor and pass string straight in to get same value. It might be something with the range of the double and parsing it. This is your solution.

final BigDecimal bigDecimal = new BigDecimal(sum);
share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.