File APIs for Java Developers Manipulate DOC, XLS, PPT, PDF and many others from your application. http://aspose.com/file-tools
Big Moose Saloon
 Search | Java FAQ | Recent Topics Register / Login Win a copy of The Mikado Method this week in the Agile and other Processes forum!

# Rounding of doubles for infinitely long numbers

Mat Austin
Greenhorn

Joined: Dec 01, 2006
Posts: 7
Hi,

I am trying to uderstand the maths behind doubles (and floats). It seems that if you divide 1.0 by 3, assign a double reference to this number and then multiply the result by 3, then you get 1.0 again.

Obviously this is what you want and the answer is correct. However, I would be grateful if someonoe could explain how java processes this. Since the double is only finitely long, it would need to be rounded at some point. Therefore, how does the JVM know that the instance variable is actually 1 / 3 and not 0.3333333...

Matt
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
It doesn't. You just happen to have got lucky that the rounding errors cancel out in this case.

When using floating-point arithmetic, you can never trust the last digit. Certain types of calculation, particularly subtracting very similar numbers, increase rounding errors so they can creep into more digits. With very complex calculations, it can go completely wrong.

This is not a feature of Java, it's a feature of floating-point. There are many occasions when floating-point is a good choice, but there are many when it isn't. The most common situation where floating point should be avoided is calculations involving currency. Those should be done in integer arithmetic, which is exact, whenever possible.

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.<br /> <br />#:^P
Mat Austin
Greenhorn

Joined: Dec 01, 2006
Posts: 7

There is one thing that I'm still not quite clear on, though. In the following code...
double x = 1.0 / 3.0;
double y = x * 3.0;
System.out.println( y ) ;

The return value is 1.0. When x is inititalised it has to be rounded at some point. Therefore is is either 0.3333.....3 or 0.3333...4. So when you multiple x by 3 you should either get 0.9999...9 or 1.0000...2.

You said that it is chance that the rounding errors cancel out in this case but I'm not entirely clear how this can work? I would be really grateful for any further feedback.

Thanks
Matt
Jesper de Jong
Java Cowboy
Bartender

Joined: Aug 16, 2005
Posts: 12921

3

Floating point numbers in a float or double are stored using the IEEE 754 floating point standard. Ofcourse the precision is limited, because only a limited number of bits is available (32 bits for a float, 64 bits for a double).

Note that floating point numbers are stored using bits - binary digits - like every piece of information in a computer. So a number like 0.33333.... isn't rounded to 0.3333...3 somewhere (that's just the decimal representation). The Wikipedia example I provided a link to above explains in detail how the bits are laid out in a float or double.

If you want to know the exact details, then you can work out what the bit pattern is of the variables x and y and what happens exactly.

Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Mat Austin
Greenhorn

Joined: Dec 01, 2006
Posts: 7
Thanks very much Jesper.

The link has totally cleared up the problem.

I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to run our stuff on 16 servers instead of 3.

subject: Rounding of doubles for infinitely long numbers