在.net中,如何在Decimal和Double之间进行选择

时间:2022-07-22 11:17:58

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

我们前几天正在讨论这个问题,我希望有一个*问题,我会指点人们这样做。)

  • What is the difference between a Double and a Decimal?
  • Double和Decimal有什么区别?
  • When (in what cases) should you always use a Double?
  • 何时(在什么情况下)你应该总是使用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 are 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.

有很多问题与这个问题重叠,但它们往往会问某个人在特定情况下应该做什么,而不是如何在一般情况下做出决定。

3 个解决方案

#1


35  

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.

自然数量是重量,高度和时间。这些永远不会被绝对准确地测量,并且很少有任何绝对精确算术的想法:你通常不应该加起来,然后确保结果完全符合预期。使用double来表示这种数量。双打范围很广,但精度有限;他们也非常快。

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 :)

主要的人为数量是金钱。有一个“完全$ 10.52”的东西,如果你加48美分,你期望有11美元。对这种数量使用小数。理由:考虑到它是人为的,所涉及的数字也是人为的,旨在满足人类需求 - 这意味着它们在基数10中自然表达。使存储表示与人类表示相匹配。 decimal不具有double的范围,但是大多数人工量也不需要额外的范围。它也比双倍慢,但我个人有一个银行账户,它给了我正确的答案,而不是一个错误的答案很快:)

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.)

有关更多信息,我有关于.NET二进制浮点类型和.NET十进制类型的文章。 (注意,十进制也是浮点类型 - 但是所讨论的“点”是小数点,而不是二进制点。)

#2


6  

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

如果你使用double并执行此操作

? ctype(1.0, Double ) / 3

you will get

你会得到

0.33333333333333331

0.33333333333333331

if you use decimal and do this

如果你使用小数并执行此操作

? ctype(1.0, Decimal ) /3

you will get

你会得到

0.3333333333333333333333333333D

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

? dou 0.0000000018446744078004519? dec 0.0000000018446744078004518913D

in the end,

到底,

double = approximation

double =近似值

decimal = real thing

小数=真实的东西

#3


1  

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.

SQL Server还值得一提的是SQL Server中的十进制映射到.net框架中的Decimal和Nullable Decimal。而在sql server中的float映射到Double和Nullable Double。以防万一你最终处理数据库应用程序。

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:

Oracle我不再使用oracle,因为你可以看到它在我的个人资料信息中被删除:),但对于那些使用oracle的人来说,这是一个映射oracle数据类型的MSDN文章:

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

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

#1


35  

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.

自然数量是重量,高度和时间。这些永远不会被绝对准确地测量,并且很少有任何绝对精确算术的想法:你通常不应该加起来,然后确保结果完全符合预期。使用double来表示这种数量。双打范围很广,但精度有限;他们也非常快。

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 :)

主要的人为数量是金钱。有一个“完全$ 10.52”的东西,如果你加48美分,你期望有11美元。对这种数量使用小数。理由:考虑到它是人为的,所涉及的数字也是人为的,旨在满足人类需求 - 这意味着它们在基数10中自然表达。使存储表示与人类表示相匹配。 decimal不具有double的范围,但是大多数人工量也不需要额外的范围。它也比双倍慢,但我个人有一个银行账户,它给了我正确的答案,而不是一个错误的答案很快:)

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.)

有关更多信息,我有关于.NET二进制浮点类型和.NET十进制类型的文章。 (注意,十进制也是浮点类型 - 但是所讨论的“点”是小数点,而不是二进制点。)

#2


6  

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

如果你使用double并执行此操作

? ctype(1.0, Double ) / 3

you will get

你会得到

0.33333333333333331

0.33333333333333331

if you use decimal and do this

如果你使用小数并执行此操作

? ctype(1.0, Decimal ) /3

you will get

你会得到

0.3333333333333333333333333333D

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

? dou 0.0000000018446744078004519? dec 0.0000000018446744078004518913D

in the end,

到底,

double = approximation

double =近似值

decimal = real thing

小数=真实的东西

#3


1  

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.

SQL Server还值得一提的是SQL Server中的十进制映射到.net框架中的Decimal和Nullable Decimal。而在sql server中的float映射到Double和Nullable Double。以防万一你最终处理数据库应用程序。

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:

Oracle我不再使用oracle,因为你可以看到它在我的个人资料信息中被删除:),但对于那些使用oracle的人来说,这是一个映射oracle数据类型的MSDN文章:

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

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