我正在为一个项目处理一些SQL,但是我注意到在SQL Server中一些看似奇怪的行为,即用小数除法得到的答案是什么样的。
以下是一些示例,这些示例说明了我所看到的行为:
DECLARE @Ratio Decimal(38,16) SET @Ratio = CAST(210 as Decimal(38,16))/CAST(222 as Decimal(38,16)); select @Ratio -- Results in 0.9459450000000000 DECLARE @Ratio Decimal(38,16) SET @Ratio = CAST(210 as Decimal)/CAST(222 as Decimal); select @Ratio -- Results in 0.9459459459459459
对于上面的代码,(似乎)不太精确的查询答案给出了更精确的值作为答案。当我同时将被除数和除数都设置为时Decimal(38,16),我得到一个小数位数为6的数字(将其转换为a会Decimal(38,16)导致0填充小数位数)。
Decimal(38,16)
当我将除数和除数仅转换为默认的十进制,而没有手动设置精度或小数位数时,我得到的结果小数位数全为16位。
出于好奇,我开始使用以下查询对它进行更多的实验:
select CAST(210 as Decimal(38,16))/CAST(222 as Decimal(38,16)) --0.945945 select CAST(210 as Decimal(28,16))/CAST(222 as Decimal(28,16)) --0.9459459459 select CAST(210 as Decimal(29,16))/CAST(222 as Decimal(29,16)) --0.945945945
如您所见,随着我提高精度,答案的规模似乎减小了。我看不到结果的规模与被除数和除数的规模或精度之间的相关性。
我发现了一些其他问题,这些问题指向msdn文档中的某个位置,该位置指出通过对除数和除数的精度和小数位数进行一组计算,可以确定对小数进行运算时得到的精度和小数位数,并且:
结果精度和小数位的绝对最大值为38。当结果精度大于38时,相应的小数位会减小,以防止结果的整数部分被截断。
因此,我自己尝试遍历这些方程式,以确定将aDecimal(38,16)分解为另一个的Decimal(38,16)结果,根据我的发现,我仍然应该获得比我更精确的数字。
所以我做错了数学,或者这是我所缺少的其他事情。非常感谢您提供的任何见解。
提前致谢…
关于价值的奥秘以及何时应用该函数,文档尚不完整,但这是基于该文档的调查结果表。6``max
6``max
如其所言,除法公式为:
结果精度= p1-s1 + s2 + max(6,s1 + p2 + 1) ,结果标度= max(6,s1 + p2 + 1)
并且,正如您自己突出显示的那样,我们将添加脚注:
因此,这是我在电子表格中生成的内容:
p1 s1 p2 s2 prInit srInit prOver prAdjusted srAdjusted 38 16 38 16 93 55 55 38 6 28 16 28 16 73 45 35 38 10 29 16 29 16 75 46 37 38 9
因此,我正在使用pr和sr指示结果的精度和小数位数。该prInit和srInit的公式是完全从文档的forumlas。我们可以看到,在所有3种情况下,结果的精度都远远大于38,因此脚注适用。prOver只是max(0,prInit - 38)-如果脚注适用,我们必须调整多少精度。prAdjusted就是prInit - prOver。在这三种情况下,我们都可以看到结果的最终精度为38。
pr
sr
prInit
srInit
38
prOver
max(0,prInit - 38)
prAdjusted
prInit - prOver
如果我申请了 相同的 调整因子,去鳞,那么我会得到的结果0,10和9。但是我们可以看到,您针对该(38,16)案例的结果的等级为6。因此,我认为那是max(6,...文档部分实际适用的地方。所以我的最终公式srAdjusted是max(6,srInit-prOver),现在我的最终Adjusted值似乎与您的结果匹配。
0
10
9
(38,16)
6
max(6,...
srAdjusted
max(6,srInit-prOver)
Adjusted
而且,当然,如果我们参考的文档decimal,我们可以看到 默认 精度和小数位数(如果您未指定的话)为(18,0),因此这是未指定精度和小数位数的行:
decimal
(18,0)
p1 s1 p2 s2 prInit srInit prOver prAdjusted srAdjusted 18 0 18 0 37 19 0 37 19