我在我的交易软件中使用double
类型的价格。
我注意到有时会出现奇怪的错误。
如果价格在“点”之后包含4位数,则会出现,如2.1234。
当我从我的程序“2.1234”发送市场订单时,价格为“2.1235”。
我不使用decimal
,因为我不需要“极端”的精确度。我不需要将“2.00000000003”与“2.00000000002”区分开来。我需要一个点后最多6位数。
问题是 - 线路在哪里?何时使用decimal
?
我应该使用decimal
进行任何财务操作吗?即使我只需要点后一位数字? (1.1 1.2等)
我知道decimal
非常慢,所以我更愿意使用double
,除非绝对需要decimal
。
答案 0 :(得分:29)
每当您处理您希望(并且可以)在base-10中完全表示的数量时,请使用小数。这包括货币价值,因为您希望2.1234完全表示为2.1234。
在base-10中不需要精确表示时使用double。这通常适用于处理测量,因为这些已经是近似值,而不是精确数量。
当然,如果基数为10的确切表示对您来说不重要,则会考虑其他因素,根据具体情况可能会或可能不重要:
答案 1 :(得分:6)
如果需要准确性且重要,请使用decimal
。
如果准确性不重要,那么您可以使用double
。
在您的情况下,您应该使用decimal
作为其财务问题。
答案 2 :(得分:4)
使用它构建的decimal
代表10井的功率(即价格)。
答案 3 :(得分:4)
对于财务操作,我总是使用小数类型
答案 4 :(得分:3)
在处理价格时,十进制是 的方式。
答案 5 :(得分:3)
如果是财务软件,您应该使用小数。 This wiki article总结得非常好。
答案 6 :(得分:3)
此示例中有一个简单的响应:
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
使用double的测试失败,因为其二进制表示(基数2)中的0.3是周期性的,因此松散精度小数由BCD表示,因此基数为10,并且您没有显着松散数字意外。不幸的是,十进制数据显然比双重慢。通常我们使用十进制进行财务计算,其中必须考虑任何数字以避免公差,工程的双重/浮动。
答案 7 :(得分:1)
Double表示通用浮点数据类型,十进制特别适用于货币和金融域。尽管double通常可以正常工作,但在某些情况下可以防止出现问题(例如,当您获得数十亿的值时出现舍入错误)
答案 8 :(得分:1)
答案 9 :(得分:0)
一旦开始对双打进行计算,您可能会遇到意外的舍入问题,因为double使用数字的二进制表示,而decimal使用保留小数位的十进制表示。这可能就是你所经历的。如果你只对序列化和反序列化双打到文本或数据库而不进行任何舍入,你实际上不会失去任何精度。
但是,在您关注十进制数字(而不是双重内部使用的二进制数字)时,小数更适合表示货币值。但是如果你需要进行复杂的计算(例如精算计算所使用的积分),你必须在进行计算之前将小数转换为double,否定使用小数的优点。
小数也会“记住”它有多少位数,例如即使十进制1.230等于1.23,第一个仍然知道尾随零,并且如果格式化为文本则可以显示它。
答案 10 :(得分:0)
如果你总是知道你将拥有的最大小数位数(点后的数字)。然后最好的做法是使用定点表示法。这将为您提供精确的结果,同时仍能快速工作。
使用固定点的最简单方式是将数字简单地存储在一千个零件中。例如,如果价格总是有2位小数,那么你将节省美分的金额(12.45美元存储在一个1245英镑的int中,因此代表1245美分)。有四个小数,你将存储一万个(12.3456将存储在一个int值123456,代表123456万分之一)等等。
这样做的缺点是,如果您将两个值相乘(0.1 * 0.1 = 0.01
而1 * 1 = 1
,则单位已从十分之一变为百分之一),有时您需要进行转换。如果你打算使用其他一些数学函数,你也必须考虑这样的事情。
另一方面,如果小数位数使用固定点变化很多是一个坏主意。如果需要高精度浮点计算,则构造十进制数据类型就是为了这个目的。