2009-01-08 81 views
16

有谁知道为什么,使用SQLServer的2005T-SQL十进制分割精度

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

+0

BTW Windows计算器给11.744389697096595117576772760941 – inspite 2009-01-08 11:53:18

回答

23

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

但分裂只是把你的头脑分开。我现在要躺下来了。

在SQL方面,虽然,它是exactly as expected.

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

你可以做同样的数学,如果遵循this rule过,如果你把每个数字对作为

  • 146804871.212533000000000和12499999.999900000
  • 146804871.212533000000000和12499999.999900000000000
+0

谢谢。说实话,我用FLOAT来解决我的特殊问题(因为我不需要100%准确),但是当我使用小数时会发生什么事情,我很困惑。 – 2009-01-08 13:18:26

+1

不幸的是,SQL服务器在算术上非常糟糕:(所以,值得一提的是,如果你需要在t-sql中进行乘法和除法的精确结果,最好的选择是:定义和使用CLR函数。 ://www.skylinetechnologies.com/Insights/Skyline-Blog/March-2013/CLR-Functions-in-SQL-Server-A-Tutorial for a good intro – 2016-03-19 21:36:40

2

转换表达而不是争论。

select CONVERT(DECIMAL(38,36),146804871.212533/12499999.9999) 
14

简而言之,使用DECIMAL(25,13),所有计算结果都可以正常工作 - 您将得到如下声明的精确度:小数点前12位数,后13位十进制数。 规则是:p + s必须等于38,你会安全的! 这是为什么? 由于SQL Server中的算术实现非常糟糕! 直到他们解决它,遵循该规则。

+0

是否有任何参考资料可以说明为什么这将是“罚款“对于所有计算? – MrEdmundo 2013-11-05 17:11:14

8

我已经注意到,如果你投的分割值浮动,它给你正确的答案,即:

select 49/30     (result = 1) 

将成为:

select 49/cast(30 as float) (result = 1.63333333333333) 
4

我们琢磨不透的魔力过渡,

P & S被连接,所以:

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

  2. (84,54) - >(38,8)

假设(38,29)被一个错字,并应(38,20),以下是数学公式:

  1. i。72 - 38 = 34, ii。 54 - 34 = 20

  2. i。 84 - 58 = 46, ii。 54 - 46 = 8

这是推理:

我。输出精度减去最大精度是我们要扔掉的数字。

ii。然后输出规模减去我们要扔掉的东西给我们......输出比例中的剩余数字。

希望这可以帮助其他人试图理解这一点。

0

它可以帮助:

SELECT COL1 * 1.0/COL2