• Post Reply Bookmark Topic Watch Topic
  • New Topic

Rounding of doubles for infinitely long numbers  RSS feed

 
Mat Austin
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...

Thanks in advance,
Matt
 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Mat Austin
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cool. Thanks for your help.

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
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Mat Austin
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks very much Jesper.

The link has totally cleared up the problem.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!