Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Precision for double literals

 
Lee Bulmer
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fairly trivial question...



Running this gives the output:

d = 0.8999999999999999
d2 = 0.9

What's bugging me is the second line in the output. It's not possible to store the value 0.9 precisely in the double variable, hence the first line of the output. That's fine. I get that. But, that being the case, I don't really understand why the second line doesn't print "d2 = 0.8999999999999999". How is the value 0.9 being held precisely between lines 2 and 4. I'm just curious about what is happening under-the-hood and I can't seem to find the relevant part of the JLS to explain it.

Thanks in advance.
 
Henry Wong
author
Marshal
Pie
Posts: 20900
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm just curious about what is happening under-the-hood and I can't seem to find the relevant part of the JLS to explain it.


The floating point formats (and behavior) is not defined in the JLS. Java uses the IEEE standard for floating points -- 32 bit and 64 bit standard.

Henry
 
Lee Bulmer
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
I'm just curious about what is happening under-the-hood and I can't seem to find the relevant part of the JLS to explain it.


The floating point formats (and behavior) is not defined in the JLS. Java uses the IEEE standard for floating points -- 32 bit and 64 bit standard.

Henry


OK, I see that in the JLS. But, as I understand it*, it specifies how floating point numbers are encoded into binary. Using this encoding it's not possible to precisely specify the number 0.9 (for example). This causes the rounding error in the assignment to variable d in the example I posted. This same rounding error does not occur in the assignment to variable d2. This leads to to believe that the JVM is not using IEEE 754 to encode the literal 0.9 in the assignment to d2.

If this behaviour is explained somewhere in IEEE 754, I've missed it. I also cannot see anything in the JLS that suggests the JVM ever uses anything other than IEEE 754 to encode floating point numbers. Obviously I've missed something in one of the two specifications. So, if you happen to know a part of IEEE 754 spec that would explains this, I would be very grateful if you could point it out as it's esaping me for the moment.

Thanks for the reply,

Lee.
* I admit my understanding may not be perfect, hence the post.
 
Campbell Ritchie
Sheriff
Posts: 48440
56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have never actually read IEEE754(1985) which I think is now called something different [but I do know what the structure of floating-point numbers is]. But it was unnecessary to explain imprecision; programmers in those days had used slide rules (I still have an old slide rule I bought about 1968) and were familiar with imprecision. Look in our FAQ (no 20) where it gives some useful links.
 
Steve Luke
Bartender
Posts: 4181
21
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It also might be worth noting that with the simple example given above, the compiler can do some optimizations because it knows the value of d is calculated from two constants when assigned. Which means the results is a constant. Which means the math can be done at compile time rather than run time. On the other hand, the value of d and d2 are never changed, so they can be replaced by constants as well. Given this code:

You can get this byte code (un-important stuff cleaned out)


So when d is encountered it is treated like the constant 0.89999...d, while when d2 is encountered it is treated as the constant 0.9d. Not sure if it helps, or is exactly pertinent to your question, but it is something to keep in mind when making these sorts of comparisons.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic