• 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:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

does Double.toString() always return exact value?

 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
BigDecimal a = new BigDecimal(2.3);
System.out.println(a);
OUTPUT:
2.29999999999999982236431605997495353221893310546875

a = new BigDecimal(String.valueOf(2.3));
System.out.println(a);
OUTPUT:
2.3

is it true that Double.toString() always returns exact value?
 
Marshal
Posts: 80520
456
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No.
 
Campbell Ritchie
Marshal
Posts: 80520
456
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have you read the documentation for Double#toString()?
Look at our FAQ (no 20). It tells you about nearest value to distinguish a double from its adjacent value. It might be better to ask "does Double.toString() ever return exact value?"
 
zheng li
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you.
 
Campbell Ritchie
Marshal
Posts: 80520
456
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome
 
zheng li
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
double d = 2.3;
double d1 = 2.29999999999999982236431605997495353221893310546875;
System.out.println(String.format("%.100f", d));
System.out.println(String.format("%.100f", d1));
System.out.println(new BigDecimal(d));
System.out.println(new BigDecimal(d1));
// according to IEEE 754, 2.29999999999999937827510620991233736276626586914062
double d2 = 2.2999999999999996;
// according to IEEE 754, 2.29999999999999982236431605997495353221893310546875
double d3 = 2.2999999999999997;
System.out.println(String.format("%.100f", d2));
System.out.println(String.format("%.100f", d3));

OUTPUT:
2.3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2.3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2.29999999999999982236431605997495353221893310546875
2.29999999999999982236431605997495353221893310546875
2.2999999999999994000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2.3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

according to IEEE 754,
the really value of 2.3 stored in memory should be 2.29999999999999982236431605997495353221893310546875.
why are the first 2 lines 2.3?

it seems that java stores floating-point types in IEEE 754 format, but does some kind of rounding off when using them.
does anyone know why java deals with double this way?
is there any specification about it?

thanks in advance.
 
Master Rancher
Posts: 5153
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

zheng li wrote:it seems that java stores floating-point types in IEEE 754 format, but does some kind of rounding off when using them.


Correct.

zheng li wrote:does anyone know why java deals with double this way?


I would guess the creators of Java wanted the numbers to print in a more human-friendly format than what you are expecting.

zheng li wrote:is there any specification about it?


Yes, if we break your question into two parts:

If d = 2.3:

1) Why does System.out.println(d) print "2.3"?

Because println(d) ends up being specified by Double.toString(d) which says:

How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double.


In the case of 2.3, no other possible double is closer to 2.3 than the one you call d1 is, so "2.3" is sufficient to uniquely identify that value - even if it doesn't look exactly the same.

2) Why does String.format("%.100f", d) return "2.3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"?

Format specifiers are described under the API for java.util.Formatter. The part about what the ".100" part does is here:

The width is the minimum number of characters to be written to the output. If the length of the converted value is less than the width then the output will be padded by ' ' (\u0020') until the total number of characters equals the width. The padding is on the left by default. If the '-' flag is given, then the padding will be on the right.


Basically, all we need to get from this is that padding does not add any actual mathematical precision to the calculation - it just adds zeroes to what you would have gotten without the padding. Since the println(d) prints "2.3", all we get with padding is to add zeroes to it.
 
Mike Simmons
Master Rancher
Posts: 5153
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's something that may help:

This shows the possible double values in the neighborhood of 2.3:

When we write "2.3" that gets translated into the double closest to 2.3, which is on the middle line. When that value is printed, it is printed with the minimum number of digits after the decimal point which will still uniquely identify that value. And so "2.3" is sufficient, because no other double is closer to 2.3 than the value shown in the middle line.
 
zheng li
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you guys.
now i finally understand what "adjacent values" means.
 
reply
    Bookmark Topic Watch Topic
  • New Topic