aspose file tools*
The moose likes Java in General and the fly likes Problem while Adding Doubles Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Problem while Adding Doubles" Watch "Problem while Adding Doubles" New topic
Author

Problem while Adding Doubles

Bhaskar G Chaugule
Greenhorn

Joined: Oct 13, 2004
Posts: 1
We are using Java JDK 1.4.2_03.
In our application we are adding a bunch of doubles. What is happening is that when we add two doubles
say 0.02 + 0.03 the output comes as 0.05000001 instead of 0.05.
We tried with floats as well but still face this issue. We cannot round off or truncate the values.
I am attaching a sample code where you can see this happening.

Please let us know if anyone knows anything on this front.



[ Jess added a carriage return, in order to keep the screen from stretching... ]
[ October 13, 2004: Message edited by: Jessica Sant ]
Dun Dagda
Ranch Hand

Joined: Oct 12, 2004
Posts: 54
This seems like fairly standard behaviour for floating point numbers. If you want to control the format of their display, e.g. rounding them off appropriately to a certain number of decimal places, you need to do something like use the DecimalFormat class from java.text.
I have modified your class to the following, which more or less does what you want. If you have a look at the JDK documentation, you might be able to find a more modern formatting class that works even better (the solution below mostly works, but not with all your numbers for some reason).

import java.text.*;

public class AddDoubleValue {
public static void main (String [] args){
double dTotalAmount = 0;
float fTotalAmount = 0;
NumberFormat f = new DecimalFormat("#0.0#");
String [] numValues = new String [] {"0.32","0.45","0.65","0.56","0.55","0.96","0.42","0.92","0.05","0.76","0.87","0.27"};
System.out.println("\n\nusing double - \n\n");
for(int x=0; x<numValues.length; x++)
{
double tempAmount = (double)Double.parseDouble(numValues[x]);
dTotalAmount += tempAmount;
System.out.println("tempAmount = "+tempAmount+" & dTotalAmount = "+dTotalAmount);
}
System.out.println("\n\nusing float - \n\n");
for(int x=0; x<numValues.length; x++)
{
float tempAmount = (float)Float.parseFloat(numValues[x]);
fTotalAmount += tempAmount;
System.out.println("tempAmount = "+tempAmount+" & fTotalAmount = "+fTotalAmount);
}
}
}


SCJP 1.4<br />SCWCD (in progress)
Dun Dagda
Ranch Hand

Joined: Oct 12, 2004
Posts: 54
Oops! Sorry, the above code should look like this (where I actually use the DecimalFormat object to call the format method on your numbers) Doh!
:roll:



[ Jess added UBB [code] tags to perserve whitespace ]
[ October 13, 2004: Message edited by: Jessica Sant ]
Nigel Browne
Ranch Hand

Joined: May 15, 2001
Posts: 673
If you are using floats or doubles to hold currency amounts, DONT. Instead either work in the smallest monetary unit for your country and keep track of the decimal point or use the BigDecimal class to hold the values.
Jessica Sant
Sheriff

Joined: Oct 17, 2001
Posts: 4313

I'm moving this to the intermediate forum, where I think its a better fit.

Please continue the discussion there. Thanks!
Ian Darwin
author
Ranch Hand

Joined: Aug 03, 2001
Posts: 64
I talk about this in Chapter 5, Numbers. How many different real values are there? An infinite number. Does everybody understand infinity? If you look at the milky way at night, you get an idea: maybe that's a nearly-infinite number of stars. But when the Hubble Space Telescope looks into the dark spaces between the stars, it sees a clearer picture. In every area of space out there the size of the head of a pin held at arm's length, there are thousands upon thousands of galaxies , each one of them roughly the size of our own milky way galaxy. And if you could magically go to one of those far-distant galaxies ("Ahead Warp Factor 22. Make it so."), you would find, beyond the rim of star light, more dark spaces in the sky with, you guessed it, more galaxies than you can count, in every area the size of a pin.

That's my brief look at infinity.

Now back to Java. Floating point numbers are an approximation of real numbers. They only have 32 bits for float, 64 bits for double. So, no matter what floating point machine you use, it will give rounding errors for some values.

The easiest thing you can do is discard the accumulated error. One way has been mentioned, with number Format objects that only present a few significant digits.

You can also eliminate it by (again, as has been mentioned), using an integer value such as a long. In North America, you'd use cents, and just print with two digits after the decimal point. However for some currencies and some amounts even the long isn't, well, long enough, so you'd use BigInteger. But then you have object creation overhead. And they're immutable, so you create a new one every time you do an addition or subtraction.

Summary: if long fits, use that. If "close enough" works, use double. If not, use BigInteger or BigDecimal.

Ian


Ian Darwin
Many questions are answered in my Java Cookbook, 2nd Edition
r phipps
Ranch Hand

Joined: Sep 14, 2004
Posts: 60
Try this i hope it helps.


import java.text.*;

public class AddDoubleValue {
public static void main (String [] args){
double dTotalAmount = 0;
float fTotalAmount = 0;
NumberFormat f = new DecimalFormat("#0.0#");
String [] numValues = new String [] {"0.32","0.45","0.65","0.56","0.55","0.96","0.42","0.92","0.05","0.76","0.87","0.27"};
System.out.println("\n\nusing double - \n\n");
for(int x=0; x<numValues.length; x++)
{
double tempAmount = (double)Double.parseDouble(numValues[x]);
dTotalAmount += tempAmount;
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(2);
String dTotalAmountString = number.format(dTotalAmount);
System.out.println("tempAmount = "+tempAmount+" & dTotalAmount = "+dTotalAmountString);
}
System.out.println("\n\nusing float - \n\n");
for(int x=0; x<numValues.length; x++)
{
float tempAmount = (float)Float.parseFloat(numValues[x]);
fTotalAmount += tempAmount;
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(2);
String fTotalAmountString = number.format(fTotalAmount);
System.out.println("tempAmount = "+tempAmount+" & fTotalAmount = "+fTotalAmountString);
}
}
}
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Problem while Adding Doubles