views:

166

answers:

3

We were discussing this the other day at work and I wish there was a Stackoverflow question I would point people at so here goes.)

  • What is the difference between a Double and a Decimal?
  • When (in what cases) should you always use a Double?
  • When (in what cases) should you always use a Decimal?
  • What’s the driving factors to consider in cases that don’t fall into one of the two camps above?

(There a lot of questions that overlap this question, but they tend to be asking what someone should do in a given case, not how to decide in the general case)

+6  A: 

if you want to keep real precision, stay with decimal

if you want to compare value, stay with decimal

if you use double and do this

? ctype(1.0, Double ) / 3

you will get

0.33333333333333331

if you use decimal and do this

? ctype(1.0, Decimal ) /3

you will get

0.3333333333333333333333333333D

and one more example, extreme one;

  decimal dec = new decimal(1, 1, 1, false, 28);
  var dou = (double)dec;

would produce this, double would lose some precision

? dou
0.0000000018446744078004519
? dec
0.0000000018446744078004518913D

in the end,

double = approximation

decimal = real thing

Fredou
Define "real precision"... bearing in mind the result of dividing 1m by 3.
Jon Skeet
@Jon skeet, done
Fredou
are you saying that decimal is to double, like double is to float?
Ian Ringrose
double is float
Fredou
@Ian - he's saying use decimal for money and double to approximate, why do people try to be sneaky? +1 fredou
JonH
@Fredou: So you're still losing information with decimal in the 1/3 case. Again, could you define what you mean by "real precision"?
Jon Skeet
@Jon Skeet - You will lose precision either way it will never be exact. I think the wording was off but I think you get the point.
JonH
Sorry, I think the answer is only understandable by people that allready knows the answer, even if they can't explain the answer.
Ian Ringrose
Ian's comment is spot on - I already know the behaviour of double and decimal, but the idea that decimal gives you "real precision" is misleading for any intuitive idea of "real precision".
Jon Skeet
+19  A: 

I usually think about natural vs artificial quantities.

Natural quantities are things like weight, height and time. These will never be measured absolutely accurately, and there's rarely any idea of absolutely exact arithmetic on it: you shouldn't generally be adding up heights and then making sure that the result is exactly as expected. Use double for this sort of quantity. Doubles have a huge range, but limited precision; they're also extremely fast.

The dominant artificial quantity is money. There is such a thing as "exactly $10.52", and if you add 48 cents to it you expect to have exactly $11. Use decimal for this sort of quantity. Justification: given that it's artificial to start with, the numbers involved are artificial too, designed to meet human needs - which means they're naturally expressed in base 10. Make the storage representation match the human representation. decimal doesn't have the range of double, but most artificial quantities don't need that extra range either. It's also slower than double, but I'd personally have a bank account which gave me the right answer slowly than a wrong answer quickly :)

For a bit more information, I have articles on .NET binary floating point types and the .NET decimal type. (Note that decimal is a floating point type too - but the "point" in question is a decimal point, not a binary point.)

Jon Skeet
+1 - I agree, with good examples.
JonH
"It's also slower than decimal, but I'd personally have a bank account"... - I believe you wanted to say "It's also slower than *double*" :)
Marek
@Marek: Thanks, will fix.
Jon Skeet
+1 As, I think "natural vs artificial" is the key to this.
Ian Ringrose
+1 This is a fantastic answer!
Andrew Hare
+1  A: 

SQL Server Its also worth mentioning that decimal in SQL Server maps to Decimal and Nullable Decimal in the .net framework. While float in sql server maps to Double and Nullable Double. Just in case you end up dealing with a database app.

Oracle I no longer work with oracle as you can see it is crossed out in my profile information :), however for those who do work with oracle here is an MSDN article mapping the oracle data types:

http://msdn.microsoft.com/en-us/library/yk72thhd(VS.80).aspx

JonH
+1, however please expand to explain how this works in oracle as well, when using oracle from .net
Ian Ringrose