user163757
user163757

Reputation: 7025

Why Is ToString() Rounding My Double Value?

How do I prevent my double value from being rounded when converting to a string? I have tried both Convert.ToString and ToString() with the same result.

For example my double may look something like 77.987654321, and the two strings conversions convert to to 77.98765. I need to keep the precision of the value as is.

Upvotes: 22

Views: 17949

Answers (6)

Robert Harvey
Robert Harvey

Reputation: 180788

Jon Skeet's DoubleConverter class has a ToExactString() method which will return the exact value of the double as a string.

https://jonskeet.uk/csharp/DoubleConverter.cs

Upvotes: 5

Jumprocks
Jumprocks

Reputation: 11

For anyone using updated versions of .NET/.NET Core:

.NET Core 3.0 introduced a breaking change that changed double.ToString() to no longer use "G15" as the default format. Instead ToString() returns the shortest string that when parsed returns the same value.

Therefore, to maintain precision, you can simply use ToString().

This is similar to older versions' "R" format specifier, but even that was apparently not 100% accurate prior to this change.

See Breaking changes in .NET Core 3.0

Upvotes: 1

I would assume that the main answer for rounding away the last two digits, is to hide numerical instability/rounding due to float/double finite precision.

Example with no rounding:

(Math.Sqrt(7)).ToString("G17") = "2.6457513110645907"

(Math.Sqrt(7)+6).ToString("G17") = "8.6457513110645898"

Looks a bit strange in the last 3 digits, right?

Example with rounding:

(Math.Sqrt(7)).ToString() = "2.64575131106459"

(Math.Sqrt(7)+6).ToString() = "8.64575131106459"

Look "perfect", right?

:-)

Upvotes: 2

Simon P Stevens
Simon P Stevens

Reputation: 27499

By default the .ToString() method of Double returns 15 digits of precision. If you want the full 17 digits that the double value holds internally, you need to pass the "G17" format specifier to the method.

String s = value.ToString("G17");

Sourced from the MSDN docs:

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.

Upvotes: 26

Andrey Shchekin
Andrey Shchekin

Reputation: 21599

No guarantees, but try ToString("R").

Upvotes: 0

Thomas
Thomas

Reputation: 181745

Try something like

myDouble.ToString("R")

See also The Round-trip ("R") Format Specifier:

The round-trip ("R") format specifier guarantees that a numeric value that is converted to a string will be parsed back into the same numeric value.

Upvotes: 16

Related Questions