gpt4 book ai didi

SQL 服务器 : Decimal Precision/Scale are yielding strange results

转载 作者:行者123 更新时间:2023-12-01 12:40:31 24 4
gpt4 key购买 nike

我正在为一个项目编写一些 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 的数字(将其转换为 Decimal(38,16) > 再次导致 0 填充比例)。

当我将被除数和除数转换为默认小数时,没有手动设置精度或比例,我得到了结果比例中的完整 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

如您所见,随着精度的提高,答案的规模似乎在缩小。我看不到结果的规模与股息和除数的规模或精度之间的相关性。

我发现其他一些 SO 问题指向 msdn 文档中的一个地方,该文档指出在小数运算期间产生的精度和小数位数是通过对除数和被除数的精度和小数位数执行一组计算来确定的,并且:

The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.

所以我尝试自己运行这些方程式以确定将一个 Decimal(38,16) 分成另一个 Decimal(38,16) 的输出是什么样子,根据我的发现,我仍然应该得到比我得到的更精确的数字。

所以我要么做错了数学,要么这里发生了一些我遗漏的事情。如果您能提供任何见解,我将不胜感激。

提前致谢...

最佳答案

documentation关于值 6 的魔力以及何时应用 max 函数有点不完整,但这是我根据该文档得出的发现的表格。

正如它所说,除法公式是:

Result precision = p1 - s1 + s2 + max(6, s1 + p2 + 1), Result scale = max(6, s1 + p2 + 1)

而且,正如您自己强调的那样,我们有脚注:

The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.

所以,这是我在电子表格中生成的内容:

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

因此,我使用 prsr 来指示结果的精度和小数位数。 prInitsrInit 公式正是文档中的 forumlas。正如我们所见,在所有 3 种情况下,结果的精度都远远大于 38,因此脚注适用。 prOver 只是 max(0,prInit - 38) - 如果脚注适用,我们必须将精度调整多少。 prAdjusted 就是 prInit - prOver。我们可以看到在这三种情况下,结果的最终精度都是38

如果我对比例应用相同调整因子,那么我将获得 0109。但是我们可以看到,(38,16) 案例的结果的比例为 6。所以我相信这就是文档的 max(6,... 部分实际适用的地方。所以我的 srAdjusted 的最终公式是 max(6, srInit-prOver) 现在我的最终 Adjusted 值似乎与您的结果相匹配。


当然,如果我们查阅 decimal 的文档,我们可以看到默认精度和小数位数,如果你不指定它们,都是(18,0),所以这是你没有指定时的行精度和比例:

p1 s1 p2 s2 prInit srInit prOver prAdjusted srAdjusted
18 0 18 0 37 19 0 37 19

关于SQL 服务器 : Decimal Precision/Scale are yielding strange results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25297073/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com