28

有谁知道为什么,使用 SQLServer 2005

SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)

给我11.74438969709659,

但是当我将分母上的小数位增加到 15 时,我得到的答案不太准确:

SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)

给我 11.74438969

4

6 回答 6

36

对于乘法,我们只需将每个参数中的小数位数相加(使用笔和纸)来计算输出的小数位数。

但是分裂只会让你大吃一惊。我现在要躺下。

但在 SQL 术语中,它完全符合预期。

--Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
--Scale = max(6, s1 + p2 + 1)

--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 9 + 54 = 72
--Max P = 38, P & S are linked, so (72,54) -> (38,20)
--So, we have 38,20 output (but we don use 20 d.p. for this sum) = 11.74438969709659
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)


--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 15 + 54 = 84
--Max P = 38, P & S are linked, so (84,54) -> (38,8)
--So, we have 38,8 output = 11.74438969
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)

如果您也将每个数字对视为

  • 146804871.212533000000000 和 12499999.999900000
  • 146804871.212533000000000 和 12499999.999900000000000
于 2009-01-08T12:12:36.840 回答
19

简而言之,使用 DECIMAL(25,13) 并且你会很好地进行所有计算 - 你会得到声明的正确精度:小数点前 12 位数字,之后小数点后 13 位数字。规则是:p+s 必须等于 38,这样你就安全了!为什么是这样?因为 SQL Server 中的算术实现非常糟糕!在他们修复它之前,请遵循该规则。

于 2009-04-03T10:02:18.740 回答
16

我注意到,如果您将除法值转换为浮点数,它会给您正确的答案,即:

select 49/30                   (result = 1)

会成为:

select 49/cast(30 as float)    (result = 1.63333333333333)
于 2009-12-07T13:45:41.800 回答
6

我们对神奇的过渡感到困惑,

P & S 是相关联的,所以:

  1. (72,54) -> (38,29)
  1. (84,54) -> (38,8)

假设(38,29)是一个错字,应该是 (38,20),以下是数学:

  1. 一世。72 - 38 = 34,二。54 - 34 = 20

  2. 一世。84 - 38 = 46,二。54 - 46 = 8

这就是原因:

一世。输出精度减去最大精度是我们要丢弃的数字。

ii. 然后输出比例减去我们要丢弃的东西给我们......输出比例中的剩余数字。

希望这有助于其他试图理解这一点的人。

于 2010-10-08T10:58:52.190 回答
4

转换表达式而不是参数。

select  CONVERT(DECIMAL(38,36),146804871.212533 / 12499999.9999)
于 2009-01-08T11:56:47.497 回答
1

使用以下内容可能会有所帮助:

SELECT COL1 * 1.0 / COL2
于 2017-03-16T10:09:10.847 回答