我正在为一个项目编写一些 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 文档中的一个位置,其中指出小数运算期间产生的精度和小数位数是通过对除数和被除数的精度和小数位数执行一组计算来确定的,并且:
结果精度和小数位数的绝对最大值为38。当结果精度大于38时,相应的小数位数会减小,以防止结果的整数部分被截断。
所以我尝试自己运行这些方程来确定除以 a 的输出是什么Decimal(38,16)
进入另一个Decimal(38,16)
看起来像,根据我的发现,我仍然应该得到比我得到的更精确的数字。
所以我要么做错了数学,要么这里发生了其他我错过的事情。我非常感谢你们中任何人提供的任何见解。
提前致谢...