Converting double to string without scientific notation and without losing digits

Requirements:

1. Must convert a double to a string, without losing any digits.
2. Cannot use scientific notation.

In C#, no format string exists that you can you pass into Double.ToString(format) to accomplish this, because ToString will use only 15 digits, even though a double can have 17. Although R and G17 can use 17 digits, it may or may not use scientific notation.

Please correct me if I am wrong.

Therefore, I wrote a function to do this. I'm posting it here as an optimization question. If you see flaws, feel free to point them out. I'm confident the code works, but there's plenty of room for improvement.

[Fact]
public void NumberFormats()
{
double d1 = 123456789012171.23;
double d2 = 0.0000000000000001;
double d3 = 10000000000000000;

string s1 = DoubleToString(d1);
string s2 = DoubleToString(d2);
string s3 = DoubleToString(d3);

Assert.Equal("123456789012171.23", s1);
Assert.Equal("0.0000000000000001", s2);
Assert.Equal("10000000000000000", s3);
}

private string DoubleToString(double d)
{
string R = d.ToString("R", CultureInfo.InvariantCulture).Replace(",", "");
int i = R.IndexOf('E');

if (i < 0)
return R;

string G17 = d.ToString("G17", CultureInfo.InvariantCulture);

if (!G17.Contains('E'))
return G17.Replace(",", "");

// manual parsing
string beforeTheE = R.Substring(0, i);
int E = Convert.ToInt32(R.Substring(i + 1));

i = beforeTheE.IndexOf('.');

if (i < 0)
i = beforeTheE.Length;
else
beforeTheE = beforeTheE.Replace(".", "");

i += E;

while (i < 1)
{
beforeTheE = "0" + beforeTheE;
i++;
}

while (i > beforeTheE.Length)
{
beforeTheE += "0";
}

if (i == beforeTheE.Length)
return beforeTheE;

return String.Format("{0}.{1}", beforeTheE.Substring(0, i), beforeTheE.Substring(i));
}

• take a look at this posting and it gives you some good examples on how to convert a double to a string using the string.Format() function stackoverflow.com/questions/4670218/…
– MethodMan
Dec 8, 2016 at 14:56
• a double can have 17 - No. double doesn't have 17 significant digits.
– TaW
Dec 8, 2016 at 15:01
• Not all doubles have 17 digits, but some do. I have one in my example. TaW take a look at the G17 format string and why it is important, and also take a look at how the R format string is handled. Then you'll understand the problem. Dec 10, 2016 at 17:12
• csharpindepth.com/Articles/General/FloatingPoint.aspx may be of interest. In this article there is a link to a DoubleConverter class which has a ToExactString method that may be of interest. It works very differently than yours ignoring any built in stuff and looking directly at the binary representation of the number. Obviously doesn't help with a review on your code but thought it might be of interest. Jan 8, 2017 at 17:33
• @TaW The page you linked to mentions that double has a precision of ~15-17 digits. Perhaps it has been updated since the time when you posted the comment? Aug 26, 2023 at 19:56

I know, it's a challenge convert your big doubles to string, but if you can use decimal instead of double, the conversion could be smooth.

static void Main(string[] args)
{
decimal d1 = 123456789012171.23m;
decimal d2 = 0.0000000000000001m;
decimal d3 = 10000000000000000m;

Console.WriteLine(d1);
Console.WriteLine(d2);
Console.WriteLine(d3);
}

• Unless your double is NaN, PositiveInfinity, or NegativeInfinity which aren't representable by Decimal. Mar 9, 2017 at 19:48