Recently I have had to serialize a double into text, and then get it back. The value seems to not be equivalent:
double d1 = 0.84551240822557006;
string s = d1.ToString("R");
double d2 = double.Parse(s);
bool s1 = d1 == d2;
// -> s1 is False
But according to MSDN: Standard Numeric Format Strings, the "R" option is supposed to guarantee round-trip safety.
The round-trip ("R") format specifier is used to ensure that a numeric value that is converted to a string will be parsed back into the same numeric value
Why did this happen?
It seems to me that this is simply a bug. Your expectations are entirely reasonable. I've reproduced it using .NET 4.5.1 (x64), running the following console app which uses my DoubleConverter
class.DoubleConverter.ToExactString
shows the exact value represented by a double
:
using System;
class Test
{
static void Main()
{
double d1 = 0.84551240822557006;
string s = d1.ToString("r");
double d2 = double.Parse(s);
Console.WriteLine(s);
Console.WriteLine(DoubleConverter.ToExactString(d1));
Console.WriteLine(DoubleConverter.ToExactString(d2));
Console.WriteLine(d1 == d2);
}
}
Results in .NET:
0.84551240822557
0.845512408225570055719799711368978023529052734375
0.84551240822556994469749724885332398116588592529296875
False
Results in Mono 3.3.0:
0.84551240822557006
0.845512408225570055719799711368978023529052734375
0.845512408225570055719799711368978023529052734375
True
If you manually specify the string from Mono (which contains the "006" on the end), .NET will parse that back to the original value. To it looks like the problem is in the ToString("R")
handling rather than the parsing.
As noted in other comments, it looks like this is specific to running under the x64 CLR. If you compile and run the above code targeting x86, it's fine:
csc /platform:x86 Test.cs DoubleConverter.cs
... you get the same results as with Mono. It would be interesting to know whether the bug shows up under RyuJIT - I don't have that installed at the moment myself. In particular, I can imagine this possibly being a JIT bug, or it's quite possible that there are whole different implementations of the internals of double.ToString
based on architecture.
I suggest you file a bug at http://connect.microsoft.com
See more on this question at Stackoverflow