Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Java Number to BigDecimal : best way

People also ask

What is precision BigDecimal Java?

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.

How accurate is BigDecimal?

This limits it to 15 to 17 decimal digits of accuracy. BigDecimal can grow to any size you need it to. Double operates in binary which means it can only precisely represent numbers which can be expressed as a finite number in binary. For example, 0.375 in binary is exactly 0.011.

Is BigDecimal immutable in Java?

Since BigDecimal is immutable, these operations do not modify the existing objects. Rather, they return new objects.


This is fine, remember that using the constructor of BigDecimal to declare a value can be dangerous when it's not of type String. Consider the below...

BigDecimal valDouble = new BigDecimal(0.35);
System.out.println(valDouble);

This will not print 0.35, it will infact be...

0.34999999999999997779553950749686919152736663818359375

I'd say your solution is probably the safest because of that.


Can we lose precision with toString() method ?

Kind of ... Both Float.toString() and Double.toString() only output the number of digits after the decimal separator, which is required for the output uniquely to correspond to a float or double value.

To use the 0.35 example in david99world's answer, consider the following code:

BigDecimal bd1 = new BigDecimal(0.35);

Number n = 0.35;
BigDecimal bd2 = new BigDecimal(n.toString());

System.out.println(bd1);
System.out.println(bd2);

An intuitive expectation may be that the two BigDecimal instances are identical, but the output shows that they are not:

0.34999999999999997779553950749686919152736663818359375
0.35

The first line is the exact value of the double, since 0.35 cannot be represented exactly. The second line is 0.35, since no more fractional digits are required to represent the distinct value. E.g. the statement 0.34999999999999997779553950749686919152736663818359375 == 0.35 will evaluate to true.

This is actually not a loss of precision when creating the BigDecimal, the uncertainty is already there in your "source" value. The problem is rather that the discrete values possible using e.g. a float or double value as source not necessarily will be represented by the exact equivalent in the BigDecimal instance.