Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

rounding errors with BigDecimal

Status
Not open for further replies.

kmcculler

Programmer
Jul 5, 2000
81
0
0
US
Hi, I'm having some issues with BigDecimal. I wrote a custom document that accepts only numbers and some symbols as user input for a textfield. In this document I have a method that gets the input number as a BigDecimal (there are some other methods in the application that take BD as input).
In this method I get the text, use Number to format it, get the floatvalue and use it as the only argument in a contructor of a new BigDecimal. My problem only seems to occur when the float has a decimal value and its not .5. Ive checked the floatvalue and it seems to be ok there but if I print the BigDecimal value its off. See the following example:
1.00 float shows as 1.00 BigDecimal
1.10 shows as 1.10000002
1.20 shows as 1.20000005
1.30 shows as 1.29999998
1.40 shows as 1.39999998
1.50 shows as 1.5
Anyone know how I can avoid or get around this problem?



Kris McCuller
Programmer Portiva Corp.
kmcculler@portiva.com
 
I think you should not use float as intermediate step.
Get the input from user as string and create a BigDecimal with a String.
import java.math.BigDecimal;
class bdec
{
public static void main(String args[])
{
float a = 1.23000001f;
String bString = new String("1.23000001");
BigDecimal myBec = new BigDecimal(Float.toString(a));
BigDecimal myBec2 = new BigDecimal(bString);
System.out.println(myBec);
System.out.println(myBec2);
}
}
 
From the Sun documentation :

BigDecimal
public BigDecimal(double val)
Translates a double into a BigDecimal. The scale of the BigDecimal is the smallest value such that (10scale * val) is an integer.
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding.

The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.


Parameters:
val - double value to be converted to BigDecimal.
Throws:
NumberFormatException - val if val is infinite or NaN.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top