3

I am trying to convert the double value 9007199254740992.0 to a string.

But there seems to be a rounding error (the last 2 becomes a 0):

(9007199254740992.0).ToString("#")    // Returns "9007199254740990"
(9007199254740992.0).ToString()       // Returns"9.00719925474099E+15"

First I thought that maybe the number couldn't be represented as a double. But it can. This can be seen by casting it to a long and then converting it to a string.

((long)9007199254740991.0).ToString() // Returns "9007199254740991"
((long)9007199254740992.0).ToString() // Returns "9007199254740992"

Also, I found that if I use the "R" format, it works.

(9007199254740992.0).ToString("R")    // Returns "9007199254740992"

Can anyone explain why ToString("#") doesn't return the double with the integer part at full precision?

Anders Carstensen
  • 2,949
  • 23
  • 23

1 Answers1

5

As can be seen on MSDN:

By default, the return value only contains 15 digits of precision although a maximum of 17 digits is maintained internally. If the value of this instance has greater than 15 digits, ToString returns PositiveInfinitySymbol or NegativeInfinitySymbol instead of the expected number. If you require more precision, specify format with the "G17" format specification, which always returns 17 digits of precision, or "R", which returns 15 digits if the number can be represented with that precision or 17 digits if the number can only be represented with maximum precision.

Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
Tomas Pastircak
  • 2,867
  • 16
  • 28
  • 1
    Interesting. So, if you want to convert a double to a string, and you don't know how many digits of precision it has, you should always use "R" or "G17" (if precision matters to you). This can certainly be a pitfall - I spent quite some time figuring out why my code failed. Thanks for the response. :) – Anders Carstensen Apr 13 '14 at 09:02
  • @AndersKellerCarstensen Indeed. See also another issue in [C# double to decimal precision loss](http://stackoverflow.com/questions/7453900/). It is by design. They collapse all the distinct `double` values whose string representations with the `"G15"` format are equal. That loses precision. – Jeppe Stig Nielsen Apr 13 '14 at 09:22