6

Can't find simple way to convert double to string. I need to convert large numbers without distortion. Such as:

double d = 11111111111111111111;
string s = d.ToString();
Console.WriteLine(s);
//1.11111111111111E+19

How to get string value from double value exactly the same as user enter.

11111111111111111111111 => "11111111111111111111111"

1.111111111111111111111 => "1.111111111111111111111"

Any ideas how it can be done?

Mohammad Yusuf
  • 16,554
  • 10
  • 50
  • 78
Artem Kyba
  • 855
  • 1
  • 11
  • 30
  • If you want a string, store user input as string. – Pikoh Nov 02 '16 at 09:58
  • 2
    just `.ToString()`? – Gilad Green Nov 02 '16 at 09:58
  • 3
    If you want a value that is [exactly](http://stackoverflow.com/q/588004/11683) what the user entered, `double` is not your choice. – GSerg Nov 02 '16 at 09:59
  • 1
    Possible duplicate of [Convert double to string](http://stackoverflow.com/questions/533931/convert-double-to-string) – active92 Nov 02 '16 at 09:59
  • `.ToString()` is not working correctly with large numbers. – Artem Kyba Nov 02 '16 at 10:03
  • 1
    Possible duplicate of [Double to string conversion without scientific notation](http://stackoverflow.com/questions/1546113/double-to-string-conversion-without-scientific-notation) – GSerg Nov 02 '16 at 10:04
  • have a look at [this dotnetfiddle](https://dotnetfiddle.net/wjfqeo) – mmushtaq Nov 02 '16 at 10:07
  • Having tested, this is very interesting - the number is so large that the compiler (at least in .NET Fiddle) will turn it into scientific notation in memory, causing even a literal string version to turn into `11111111111111100000` – Alfie Goodacre Nov 02 '16 at 10:08
  • @AlfieGoodacre This is how floating point numbers are stored in principle. It is not about how big the number is. Please see http://stackoverflow.com/q/588004/11683. – GSerg Nov 02 '16 at 10:13
  • In your example, you're not using any decimals. If you only need to support whole numbers, you might want to consider using [BigInteger](https://msdn.microsoft.com/en-us/library/system.numerics.biginteger%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) – Matthew Watson Nov 02 '16 at 10:33

3 Answers3

8

double is a floating point type. So it has a limited accuracy. In your example, you could do something like this:

double d = 11111111111111111111;
string s = d.ToString("F0");
Console.WriteLine(s);

But as you'll see,this would output 11111111111111100000 instead of 11111111111111111111,so it has lost accuracy in the process. So the answer here is use the right type for the work. If you need a string, use a string variable to store the value.

Edit

This was the question i was trying to find that explains the problem with floating point math., thanks to @GSerg

Community
  • 1
  • 1
Pikoh
  • 7,582
  • 28
  • 53
2

First of all: 11111111111111111111111 is to large for a double value and also this value: 1.111111111111111111111 since the double max decimal length is 17.

By default, a Double value contains 15 decimal digits of precision, although a maximum of 17 digits is maintained internally.

For this reason you should use BigInteger and then ToString for formatting the output.
There is also a library in the nuget Directory called BigRational, never used and seems in Beta stage but probably will help in solving this problem.

Tinwor
  • 7,765
  • 6
  • 35
  • 56
1

In general case, you can't do this: user can well input, say 123, in many a way:

  • 123
  • 123.00
  • 1.23e2
  • 12.3E1
  • 123.0e+00
  • 1230e-1

etc. When you convert the user input into double you loose the initial format:

string userInput = ...

// double is just 123.0 whatever input has been
double value = double.Parse(userInput);

In case you want to drop exponent if it's possible you can

double value = 11111111111111111111;

string result = value.ToString("#######################");

And, please, notice, that double has 64 bit to store the value, that's why a distortion is inevitable for large numbers:

// possible double, which will be rounded up
double big = 123456789123456789123456789.0;

// 1.2345678912345679E+26
Console.WriteLine(big.ToString("R"));
// 123456789123457000000000000
Console.WriteLine(big.ToString("###########################")); 

May be you want BigInteger instead of double:

using System.Numerics;

...

BigInteger value = BigInteger.Parse("111111111111111111111111111111111"); 

// 111111111111111111111111111111111
Console.WriteLine(value.ToString());
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215