如何决定使用什么 - 双倍或小数? [重复]

时间:2020-12-30 17:06:32

Possible Duplicate:
decimal vs double! - Which one should I use and when?

可能重复:十进制vs双! - 我应该使用哪一个?何时使用?

I'm using double type for price in my trading software. I've noticed that sometimes there are a odd errors. They occur if price contains 4 digits after "dot", like 2.1234.

我在交易软件中使用双重价格。我注意到有时会出现奇怪的错误。如果价格在“点”之后包含4位数,则会出现,如2.1234。

When I sent from my program "2.1234" on the market order appears at the price of "2.1235".

当我从我的程序“2.1234”发送市场订单出现在“2.1235”的价格。

I don't use decimal because I don't need "extreme" precision. I don't need to distinguish for examle "2.00000000003" from "2.00000000002". I need maximum 6 digits after a dot.

我不使用十进制,因为我不需要“极端”精度。我不需要将“2.00000000003”与“2.00000000002”区分开来。我需要一个点后最多6位数。

The question is - where is the line? When to use decimal?

问题是 - 线路在哪里?什么时候使用小数?

Should I use decimal for any finansical operations? Even if I need just one digit after the dot? (1.1 1.2 etc.)

我应该对任何金融业务使用小数吗?即使我在点之后只需要一位数字? (1.1 1.2等)

I know decimal is pretty slow so I would prefer to use double unless decimal is absolutely required.

我知道小数很慢所以我更喜欢使用double,除非十进制是绝对必需的。

11 个解决方案

#1


28  

Use decimal whenever you're dealing with quantities that you want to (and can) be represented exactly in base-10. That includes monetary values, because you want 2.1234 to be represented exactly as 2.1234.

无论何时处理您想要(并且可以)完全表示在基数10中的数量,都要使用小数。这包括货币价值,因为您希望2.1234完全表示为2.1234。

Use double when you don't need an exact representation in base-10. This is usually good for handling measurements, because those are already approximations, not exact quantities.

当你不需要在base-10中使用精确表示时,请使用double。这通常适用于处理测量,因为这些已经是近似值,而不是精确量。

Of course, if having or not an exact representation in base-10 is not important to you, other factors come into consideration, which may or may not matter depending on the specific situation:

当然,如果基数为10的确切表示对您来说不重要,则会考虑其他因素,根据具体情况,这些因素可能或可能不重要:

  • double has a larger range (it can handle very large and very small magnitudes);
  • double具有更大的范围(它可以处理非常大和非常小的幅度);
  • decimal has more precision (has more significant digits);
  • 十进制有更多精度(有更多有效数字);
  • you may need to use double to interact with some older APIs that are not aware of decimal;
  • 您可能需要使用double来与一些不知道小数的旧API进行交互;
  • double is faster than decimal;
  • double比十进制快;
  • decimal has a larger memory footprint;
  • decimal有更大的内存占用;

#2


6  

When accuracy is needed and important, use decimal.

当需要准确性且重要时,请使用小数。

When accuracy is not that important, then you can use double.

如果准确性不重要,那么你可以使用double。

In your case, you should be using decimal, as its financial matter.

在您的情况下,您应该使用十进制,作为其财务问题。

#3


4  

For financial operation I always use the decimal type

对于财务操作,我总是使用小数类型

#4


4  

Use decimal it's built for representing powers of 10 well (i.e. prices).

使用十进制数来表示10井的功率(即价格)。

#5


3  

Decimal is the way to go when dealing with prices.

十进制是处理价格时的方法。

#6


3  

If it's financial software you should probably use decimal. This wiki article summarises quite nicely.

如果是财务软件,您应该使用小数。这篇维基文章很好地总结了一下。

#7


2  

A simple response is in this example:

这个例子中有一个简单的响应:

decimal d = 0.3M+0.3M+0.3M;
            bool ret = d == 0.9M; // true
            double db = 0.3 + 0.3 + 0.3;
            bool dret = db == 0.9; // false

the test with the double fails since 0.3 in its binary representation ( base 2 ) is periodic, so you loose precision the decimal is represented by BCD, so base 10, and you did not loose significant digit unexpectedly. The Decimal are unfortunately dramattically slower than double. Usually we use decimal for financial calculation, where any digit has to be considered to avoid tolerance, double/float for engineering.

使用double的测试失败,因为它的二进制表示(基数2)中的0.3是周期性的,所以你松散精度小数由BCD表示,所以基数为10,并且你没有意外地丢失有效数字。不幸的是,Decimal很快就会慢一倍。通常我们使用十进制进行财务计算,其中必须考虑任何数字以避免容差,工程的双重/浮动。

#8


1  

Double is meant as a generic floating-point data type, decimal is specifically meant for money and financial domains. Even though double usually works just fine decimal might prevent problems in some cases (e.g. rounding errors when you get to values in the billions)

Double表示通用浮点数据类型,十进制特别适用于货币和金融域。尽管double通常可以正常工作,但在某些情况下可以防止出现问题(例如,当您获得数十亿的值时出现舍入错误)

#9


1  

There is an Explantion of it on MSDN

在MSDN上有一个解释

#10


0  

As soon as you start to do calculations on doubles you may get unexpected rounding problems because a double uses a binary representation of the number while the decimal uses a decimal representation preserving the decimal digits. That is probably what you are experiencing. If you only serialize and deserialize doubles to text or database without doing any rounding you will actually not loose any precision.

一旦开始对双打进行计算,您可能会遇到意外的舍入问题,因为double使用数字的二进制表示,而decimal使用保留小数位的十进制表示。这可能就是你所经历的。如果您只对序列化和反序列化双精度到文本或数据库而不进行任何舍入,您实际上不会失去任何精度。

However, decimals are much more suited for representing monetary values where you are concerned about the decimal digits (and not the binary digits that a double uses internally). But if you need to do complex calculations (e.g. integrals as used by actuary computations) you will have to convert the decimal to double before doing the calculation negating the advantages of using decimals.

但是,小数更适合表示您关注十进制数字的货币值(而不是双重内部使用的二进制数字)。但是如果你需要进行复杂的计算(例如精算计算所使用的积分),你必须在进行计算之前将小数转换为double,否定使用小数的优点。

A decimal also "remembers" how many digits it has, e.g. even though decimal 1.230 is equal to 1.23 the first is still aware of the trailing zero and can display it if formatted as text.

小数也“记住”它有多少位数,例如即使十进制1.230等于1.23,第一个仍然知道尾随零,并且如果格式化为文本则可以显示它。

#11


0  

If you always know the maximum amount of decimals you are going to have (digits after the point). Then the best practice is to use fixed point notation. That will give you an exact result while still working very fast.

如果你总是知道你将拥有的最大小数位数(点后面的数字)。然后最好的做法是使用定点表示法。这将为您提供精确的结果,同时仍然可以非常快速地工作。

The simplest manner in which to use fixed point is to simply store the number in an int of thousand parts. For example if the price always have 2 decimals you would be saving the amount of cents ($12.45 is stored in an int with value 1245 which thus would represent 1245 cents). With four decimals you would be storing pieces of ten-thousands (12.3456 would be stored in an int with value 123456 representing 123456 ten-thousandths) etc etc.

使用固定点的最简单方式是将数字简单地存储在一千个零件中。例如,如果价格总是有2位小数,那么你将节省美分金额(12.45美元存储在一个1245英镑的int中,因此代表1245美分)。使用四位小数就可以存储一万个(12.3456将存储在int中,值123456代表123456万分之一)等等。

The disadvantage of this is that you would sometimes need a conversion if for example you are multiplying two values together (0.1 * 0.1 = 0.01 while 1 * 1 = 1, the unit has changed from tenths to hundredths). And if you are going to use some other mathematical functions you also has to take things like this into consideration.

这样做的缺点是,如果您将两个值相乘(0.1 * 0.1 = 0.01而1 * 1 = 1,单位从十分之一变为百分之一),您有时需要进行转换。如果你打算使用其他一些数学函数,你也必须考虑这样的事情。

On the other hand if the amount of decimals vary a lot using fixed point is a bad idea. And if high-precision floating point calculations are needed the decimal datatype was constructed for exactly that purpose.

另一方面,如果小数位数使用固定点变化很多是一个坏主意。如果需要高精度浮点计算,则为此目的构造十进制数据类型。

#1


28  

Use decimal whenever you're dealing with quantities that you want to (and can) be represented exactly in base-10. That includes monetary values, because you want 2.1234 to be represented exactly as 2.1234.

无论何时处理您想要(并且可以)完全表示在基数10中的数量,都要使用小数。这包括货币价值,因为您希望2.1234完全表示为2.1234。

Use double when you don't need an exact representation in base-10. This is usually good for handling measurements, because those are already approximations, not exact quantities.

当你不需要在base-10中使用精确表示时,请使用double。这通常适用于处理测量,因为这些已经是近似值,而不是精确量。

Of course, if having or not an exact representation in base-10 is not important to you, other factors come into consideration, which may or may not matter depending on the specific situation:

当然,如果基数为10的确切表示对您来说不重要,则会考虑其他因素,根据具体情况,这些因素可能或可能不重要:

  • double has a larger range (it can handle very large and very small magnitudes);
  • double具有更大的范围(它可以处理非常大和非常小的幅度);
  • decimal has more precision (has more significant digits);
  • 十进制有更多精度(有更多有效数字);
  • you may need to use double to interact with some older APIs that are not aware of decimal;
  • 您可能需要使用double来与一些不知道小数的旧API进行交互;
  • double is faster than decimal;
  • double比十进制快;
  • decimal has a larger memory footprint;
  • decimal有更大的内存占用;

#2


6  

When accuracy is needed and important, use decimal.

当需要准确性且重要时,请使用小数。

When accuracy is not that important, then you can use double.

如果准确性不重要,那么你可以使用double。

In your case, you should be using decimal, as its financial matter.

在您的情况下,您应该使用十进制,作为其财务问题。

#3


4  

For financial operation I always use the decimal type

对于财务操作,我总是使用小数类型

#4


4  

Use decimal it's built for representing powers of 10 well (i.e. prices).

使用十进制数来表示10井的功率(即价格)。

#5


3  

Decimal is the way to go when dealing with prices.

十进制是处理价格时的方法。

#6


3  

If it's financial software you should probably use decimal. This wiki article summarises quite nicely.

如果是财务软件,您应该使用小数。这篇维基文章很好地总结了一下。

#7


2  

A simple response is in this example:

这个例子中有一个简单的响应:

decimal d = 0.3M+0.3M+0.3M;
            bool ret = d == 0.9M; // true
            double db = 0.3 + 0.3 + 0.3;
            bool dret = db == 0.9; // false

the test with the double fails since 0.3 in its binary representation ( base 2 ) is periodic, so you loose precision the decimal is represented by BCD, so base 10, and you did not loose significant digit unexpectedly. The Decimal are unfortunately dramattically slower than double. Usually we use decimal for financial calculation, where any digit has to be considered to avoid tolerance, double/float for engineering.

使用double的测试失败,因为它的二进制表示(基数2)中的0.3是周期性的,所以你松散精度小数由BCD表示,所以基数为10,并且你没有意外地丢失有效数字。不幸的是,Decimal很快就会慢一倍。通常我们使用十进制进行财务计算,其中必须考虑任何数字以避免容差,工程的双重/浮动。

#8


1  

Double is meant as a generic floating-point data type, decimal is specifically meant for money and financial domains. Even though double usually works just fine decimal might prevent problems in some cases (e.g. rounding errors when you get to values in the billions)

Double表示通用浮点数据类型,十进制特别适用于货币和金融域。尽管double通常可以正常工作,但在某些情况下可以防止出现问题(例如,当您获得数十亿的值时出现舍入错误)

#9


1  

There is an Explantion of it on MSDN

在MSDN上有一个解释

#10


0  

As soon as you start to do calculations on doubles you may get unexpected rounding problems because a double uses a binary representation of the number while the decimal uses a decimal representation preserving the decimal digits. That is probably what you are experiencing. If you only serialize and deserialize doubles to text or database without doing any rounding you will actually not loose any precision.

一旦开始对双打进行计算,您可能会遇到意外的舍入问题,因为double使用数字的二进制表示,而decimal使用保留小数位的十进制表示。这可能就是你所经历的。如果您只对序列化和反序列化双精度到文本或数据库而不进行任何舍入,您实际上不会失去任何精度。

However, decimals are much more suited for representing monetary values where you are concerned about the decimal digits (and not the binary digits that a double uses internally). But if you need to do complex calculations (e.g. integrals as used by actuary computations) you will have to convert the decimal to double before doing the calculation negating the advantages of using decimals.

但是,小数更适合表示您关注十进制数字的货币值(而不是双重内部使用的二进制数字)。但是如果你需要进行复杂的计算(例如精算计算所使用的积分),你必须在进行计算之前将小数转换为double,否定使用小数的优点。

A decimal also "remembers" how many digits it has, e.g. even though decimal 1.230 is equal to 1.23 the first is still aware of the trailing zero and can display it if formatted as text.

小数也“记住”它有多少位数,例如即使十进制1.230等于1.23,第一个仍然知道尾随零,并且如果格式化为文本则可以显示它。

#11


0  

If you always know the maximum amount of decimals you are going to have (digits after the point). Then the best practice is to use fixed point notation. That will give you an exact result while still working very fast.

如果你总是知道你将拥有的最大小数位数(点后面的数字)。然后最好的做法是使用定点表示法。这将为您提供精确的结果,同时仍然可以非常快速地工作。

The simplest manner in which to use fixed point is to simply store the number in an int of thousand parts. For example if the price always have 2 decimals you would be saving the amount of cents ($12.45 is stored in an int with value 1245 which thus would represent 1245 cents). With four decimals you would be storing pieces of ten-thousands (12.3456 would be stored in an int with value 123456 representing 123456 ten-thousandths) etc etc.

使用固定点的最简单方式是将数字简单地存储在一千个零件中。例如,如果价格总是有2位小数,那么你将节省美分金额(12.45美元存储在一个1245英镑的int中,因此代表1245美分)。使用四位小数就可以存储一万个(12.3456将存储在int中,值123456代表123456万分之一)等等。

The disadvantage of this is that you would sometimes need a conversion if for example you are multiplying two values together (0.1 * 0.1 = 0.01 while 1 * 1 = 1, the unit has changed from tenths to hundredths). And if you are going to use some other mathematical functions you also has to take things like this into consideration.

这样做的缺点是,如果您将两个值相乘(0.1 * 0.1 = 0.01而1 * 1 = 1,单位从十分之一变为百分之一),您有时需要进行转换。如果你打算使用其他一些数学函数,你也必须考虑这样的事情。

On the other hand if the amount of decimals vary a lot using fixed point is a bad idea. And if high-precision floating point calculations are needed the decimal datatype was constructed for exactly that purpose.

另一方面,如果小数位数使用固定点变化很多是一个坏主意。如果需要高精度浮点计算,则为此目的构造十进制数据类型。