• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Loss of precision in primitives

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I found this trail:
You can find there this piece of code:

Which produces:

So obviously there is a loss of precision.
Now what I don't understand is why there is no loss of precision for this piece of code:

as it produces:


Thanks,
Justyna W.
 
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Floating-point values are stored in format resembling scientific notation. For precise details, search on "IEEE 754 Standards." But basically, this means that some of the bits in a float are used to store a value, and some of the bits are used to store an exponent.

As explained by Thomas De Vos in the original thread you referenced, "A float contains as the most significant bit the sign, followed by 8 bits which represent the exponent and 23 bits for the value or called the mantissa."

Note: "...23 bits for the value."

Now, if the value is "normalized" (which means the exponent part is non-zero), then there is an implicit "1-point" preceding the value. For example, a value of 1.1001 would only need to be stored as 1001, because the "1-point" at the beginning is implied.

So allowing for the implicit "1-point," if an int value requires 24 bits or more, it will require the full 23 bits allowed for a value when stored as a float. So let's take a look at int values requiring more than 24 bits, and see what happens when they are assigned to a float, then cast back to type int.

The code below starts at a given int value, then prints the next 100 int values for which no precision is lost in the conversion to float and back. As you will see by the output, all is well until more than 24 bits are required for the int value. But at that point, gaps (loss of precision) start to appear. In particular, note the pattern at the far right of the binary representation.

To help see this pattern better, start with a higher int value, like (int)Math.pow(2, 27).
 
marc weber
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note:

For the SCJP exam, you do not need to know details of the IEEE 754 Standards. In my post above, I was just providing some background to illustrate why some int values can go to float and back with no loss, while other (smaller) values lose precision.

You do need to know that a loss of precision is possible when casting from a floating-point primitive to an integral primitive, which is why an explicit cast is required.
 
Your buns are mine! But you can have this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic