Paul Cassidy - 1 year ago 95
C# Question

# Convert.ToDouble(decimal) unexpected loss precision

Consider the following code:

double d = 1478110092.9070129;
decimal dc = 1478110092.9070129M;

Console.WriteLine(d.ToString("R"));
Console.WriteLine(dc);

Console.WriteLine(Convert.ToDouble(dc).ToString("R"));
Console.WriteLine(double.Parse(dc.ToString()).ToString("R"));

This generates the following:

1478110092.9070129
1478110092.9070129
1478110092.9070127
1478110092.9070129

My question is what is going on in Convert.ToDouble? Clearly this number can be represented in a double?

This I believe is a bug in Convert.ToDouble(decimal d). The C# spec says that conversion should give the closest double, but here it clearly doesn't. Looking at the bits, we can see that it is off by one double.

double d = 1478110092.9070129;
decimal dc = 1478110092.9070129M;
double dcd = Convert.ToDouble(dc);
long d_bits = BitConverter.DoubleToInt64Bits(d);     // 4743986451068882048
long dcd_bits = BitConverter.DoubleToInt64Bits(dcd); // 4743986451068882047