1

我们的sql server 2008中有三个表

  1. 交易订单
  2. 交易装运
  3. 交易子订单。

其中三个有一个共同的列Carrying_cost。三个表中的数据类型相同。它是浮点数,NUMERIC_PRECISION 53 和 NUMERIC_PRECISION_RADIX 2。

  1. 在表 1 - transact_orders 中,该列的三行值为 5.1。转换(十进制(20,15),携带成本)5.100000在这里返回......

  2. 表 2 - transact_shipments 三行正在从 transact_orders 中的这三行获取 Carrying_cost。转换(十进制(20,15),携带成本)5.100000在这里也返回.....。

  3. 表 3 - transact_child_orders 总结了来自 transact_shipments 的这三个持有成本。那里显示的值是15.3我运行正常选择时的值。

但在这个稳定的convert(decimal(20,15), carrying_cost)回报。它也在 ui 中15.299999999999999显示了该值。precision gained虽然 ui 只是获取值,而不是进行任何转换。在 java 代码中,从 db 中获取值的变量定义为double.

步骤3中的代码,总结了三个carrying_costs很简单::

…… sum(isnull(transact_shipments.carrying_costs,0)) sum_carrying_costs,_

知道为什么这种变化发生在第三步吗?任何帮助将不胜感激。如果需要更多信息,请告诉我。

4

1 回答 1

1

我不会发表一堆评论,而是写一个答案。


浮点数不适用于不能接受舍入误差的精确值 - 例如金融。

浮点数可以从非常小的数字扩展到非常大的数字。但他们不会在不损失一定程度的准确性的情况下这样做。您可以在线查看详细信息,那里有很多好作品供您阅读。

但是,简单地说,这是因为它们是真正的二进制数——一些十进制数不能以 100% 的准确度表示为二进制值。 (就像 1/3 不能以十进制 100% 准确度表示。)


我不确定是什么导致了 DECIMAL 数据类型的性能问题,通常是因为正在进行一些隐式转换。 (您在某处有一个浮点数,或者具有不同定义的小数等)

但不管是什么原因;没有什么比整数算术更快的了。那么,存储你的值是整数吗? £1.10可以存储为110p. 或者,如果您知道由于某种原因您会得到几分之一便士,11000dp (十便士)

然后,您确实需要考虑您将达到的最大价值,以及是否INTBIGINT合适。

此外,在处理整数时,请注意除法。如果你分成£103个人,最后一个1p需要去哪里? £3.33两个人和£3.34一个人? £0.01被银行吃掉了?但是,总是不应该得到lost to the digital elves.

而且,显然,当向用户显示数字时,您需要将其操作回£而不是dp; 但无论如何你都需要经常这样做,以获得£10kor£10M等​​。


无论您做什么,如果您不想因浮点值导致舍入错误,请不要使用 FLOAT。

(网上有很多关于如何使用浮点数的文章,更重要的是,如何不使用浮点数。这是一个很大的话题;只是不要陷入“它如此准确,令人惊叹,它可以做任何事情”的陷阱 - 我无法计算人们使用这种不幸的常见但幼稚的假设来搞砸数据的次数。)

于 2012-06-08T11:21:05.117 回答