0

Trying to parse the value -36.845167 from a string:

double result;
double.TryParse("-36.845167", out result);

result is -36.845167000000004

decimal value;
decimal.TryParse("-36.845167", out value);
double result = (double)value;

result is -36.845167

Why is this?

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
zcj
  • 20
  • 1
  • 3

2 Answers2

2

The two doubles bracketing -36.845167 are -36.84516700000000355430529452860355377197265625 and -36.84516699999999644887793692760169506072998046875

They differ from the exact value by 3.55112206307239830493927001953125E-15 and 3.55430529452860355377197265625E-15 respectively.

The first one is very slightly closer, so it is the correct IEEE 754 round-to-nearest result. I do not know what the standard requires for casting a C# decimal to double, but, assuming you used the same output method in both cases, it may not have done round-to-nearest.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
1

This is because double has limited precision, while decimal stores decimal digits. Read more here: Difference between decimal, float and double in .NET?

Basically, decimal is better at storing decimal representation of the number.

Edit: answering your original question more explicitly: Both of your results are kinda incorrect since -36.845167 cannot be represented as double. Check out the output of this expression:

 result.ToString("G20")

on both of your results and you will see that both of them are not equal to -36.845167: one of them is -36.845166999999996 and other is -36.845167000000004.

So, both of them are 4e-15 off your original number. What you really see in the debugger (or upon outputting to console) is just the rounding during the conversion to string.

Community
  • 1
  • 1
torvin
  • 6,515
  • 1
  • 37
  • 52
  • But why can the correct double be created through casting a double instead of directly with the double's TryParse method? – zcj Oct 05 '15 at 07:37