File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Arithmetic using primitive double Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Arithmetic using primitive double" Watch "Arithmetic using primitive double" New topic
Author

Arithmetic using primitive double

Michael L. Miller
Greenhorn

Joined: May 07, 2013
Posts: 3
I realize that floating point primitives in Java use IEEE 754, but why are the results from the println() displayed so inconsistently by default?

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Because you can't store the same values in base-2 "fraction-point" notation (which is how IEEE 754, the floating point standard used by Java and other languages) that you can using the same kind of notation in base-10.

For example, it is impossible to store the base-10 value 0.1 (one-tenth) exactly in base-2 no matter how many bits we use, for exactly the same reason that we can't store 1/3 exactly in base-10.

For more details, google for what every developer should know about floating point numbers.
Michael L. Miller
Greenhorn

Joined: May 07, 2013
Posts: 3
Thanks Jeff. Perhaps I made the title of the post misleading. My questions is really about how the floating point result is converted back to a String. It's kind of surprising that the result of this program:


is:
19.999999000000003
19.999999

However, the underlying results before converting to Strings are:
4033FFFFEF390860 19.9999990000000030000
4033FFFFEF39085F 19.9999989999999990000


Why doesn't the second result also print 15 decimal places?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Presumably the default format is set to cut of trailing zeros, and everything out to that position would be zeros for that expression.

And no, it's not surprising that 10 + 9.999999 yields different results from 0 + 19.999999. This is part of why we don't use == to compare FP values, but rather, check whether they're within some epsilon that we define
Michael L. Miller
Greenhorn

Joined: May 07, 2013
Posts: 3
Thanks again, Jeff. Seems like the String representations would have been:

19.999999000000003
19.999998999999999

if the algorithm set out to cut off trailing zeros.

And yes, I think it is surprising that the String representation of these two results in the JVM is not more consistent.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

The Mike Miller wrote:Thanks again, Jeff. Seems like the String representations would have been:

19.999999000000003
19.999998999999999

if the algorithm set out to cut off trailing zeros.


Most likely that second one had another 9 on the end, and so got rounded up to 19.999999000000000.


And yes, I think it is surprising that the String representation of these two results in the JVM is not more consistent.


The String representations are different because the double values are different.

Floating point arithmetic is very non-intuitive, and the order of operations matters in cases where it wouldn't if we were doing it by hand. A + B + C does not always equal C + B + A.

For example, if we start off with zero, and add something really small, like 0.0000000000001 (plus or minus a few zeros), and keep adding that value enough bazillions of times to get the value 10, and then add that 10 to the value 10000000000000000 (plus or minus a few zeros), we'll get the expected 10000000000000010, or maybe that with a .00000125 on th end. BUT if we instead start with the really big value, and then at the tiny value a few bazillion times, we end up with ... exactly the big value we started with.

This non-intuitive behavior is one of the tradeoffs that have to be made in order to have fast arithmetic over a large range with a small number of bits. In the end, though, we have about 16 decimal digits of precision, which is more than is needed for a lot of use cases. As long as we're smart about how we do our operations, and pay attention to the difference between the double value and the String representation, we'll get the results we expect.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Arithmetic using primitive double