tags:

views:

145

answers:

5
+1  Q: 

decimal to double

I have the following test code:

decimal test1 = 0.0500000000000000045656554454M;
double test2 = (double)test1;

This results in test2 showing as 0.05 when debugging. Why is it being rounded to 2 decimal places?

Thanks

+4  A: 

The reason is that double can contain no more than 15-16 significant digits.

see double (C# Reference)

Li0liQ
+1 for the C# reference. I think that it is 15-16 digits in the worst case, but in some cases it could be better than that (depending if it can actually be represented by double...)
Anna
+1, additional note: C# uses IEEE-754 for Single and Double precision floating point data.
sixlettervariables
This answer is wrong : the reason is that your debugger just doesn't display 0.05000000000000000971445146547011972870677709579467773437 as Jon has pointed out. 15/16 significant digits still is right though, but there's a difference between the numbers of digits and the numbers of significant digits.
Peter
+1  A: 

There are two reasons I can think of:

  1. Due to the different representation of decimal and double. See this article for more information about floating point representation. It is possible that there are not enough bits for the whole number representation in the double.
  2. Due to the way numbers are printed. It is possible that in your printing options, there are less than 18 numbers after the decimal point specified - in which case, you'll get the rounded result.

I would check for tweaking the printing options first to make sure that the problem isn't there first.

.. But know that the only solution for the first problem is stop using double :-)

Anna
+3  A: 

You should take a look at this article about floating-point arithmetic and .NET. The rounding occurs due to a combination of how the number gets converted to a double-precision floating point value and how it is formatted when printed, since .NET defaults to 15 decimals for doubles, and your original number contains decimal past the 15th.

You could try test2.ToString("0.000000000000000000000000") to see if you might squeeze out any more information from the number, but I doubt it will.

Cecil Has a Name
A: 

here's a link to the documentation

+3  A: 

The value from that conversion is actually 0.050000000000000009714451465470119728706777095794677734375, as shown by DoubleConverter. That's the exact value of the nearest double to the decimal you converted.

When you use the debugger or normal string formatting, you aren't usually shown the exact result.

Jon Skeet
+1 : that's why I got 0.05000000000000001 in my debugger.
Peter
OK, but why is this value then being shown as 0.05 when serialized?Thanks
Jon Archway
Good question : "you aren't usually shown the exact result" -> why not? For output formatting, ok I guess, but in a debugger this might come in handy as this question shows.
Peter
@Peter: I suspect most people don't want to see a value quite as long as the one shown here. It also gives a false impression to some extent - they may expect to be able to tweak the 25th digit, just because far more digits are shown. I've chosen to show the exact value, but the nearest exact value away from this will have a number of different significant digits.
Jon Skeet
@Jon, false impression is a good point, although debuggers should imo just show the works..
Peter
@Jon Archway (sorry for my previous @ : I didn't realize you both are Jons) : the answer to your question is : 'since .NET defaults to 15 decimals for doubles' combined with Jons answer I guess
Peter