以下TSQL语句根据@Size和@ Value的顺序返回不同的值。第一个语句返回1687.500000但第二个语句返回1687.600000。 我猜它是因为一些四舍五入但我无法弄清楚自己。任何帮助都会非常感激。
DECLARE @Amount DECIMAL(20,4) = 2,
@PriceDiff DECIMAL(25,10) = 0.421875,
@Size DECIMAL(16,4)= 200000.0000,
@Value DECIMAL(25,15)= 0.010000000000000
SELECT @Amount * @PriceDiff * @Size * @Value AS FinalValue
SELECT @Amount * @PriceDiff * @Value * @Size AS FinalValue
答案 0 :(得分:5)
您遇到舍入错误的原因是SQL Server确定Decimal类型的精度和比例的乘法结果的方式。 see here
此外,SQL Server对相同/等优先运算符的操作顺序为LTR。
鉴于第一步是多个@Amount * @PriceDiff。根据该链接,精度和规模将是:
precision = 20 + 25 + 1 = 46
scale = 4 + 10 = 14
resulting data type = Decimal(46, 14)
这个结果超过了Decimal的最大允许精度,所以事情变得有点粘。在该链接的底部,您将看到:
- 结果精度和比例的绝对最大值为38.当结果精度大于38时,相应的比例会减小,以防止结果的整数部分被截断。
Reading up on this further你会发现,而不只是删掉所有的小数位来制作一个Decimal(38,0)
或者允许所有精度为十进制的Decimal(38,38)
SQL服务器猜猜并使它成为Decimal(38,6)
。
一切都很好,但到目前为止我们的结果是0.84375
,并且适合我们新的Decimal(38,6)
容器。
您现在可以看到,如果我们将此乘以@Size,我们仍然会在Decimal(38,6)
的限制范围内,结果为168750
。因此,即使使用精度和比例数学,我们仍然很好,并且得到的舍入将达到6的标准。
但是,如果我们将0.84375
结果和@Value
precision = 38 + 25 + 1 = 64
scale = 6 + 15 = 21
result = Decimal(64, 21)
取得结果,我们就会得到:
0.0084375
这意味着我们又强制将其强制为十进制(38,6)......并且0.08438
不适合,因此它会四舍五入为"eb init"
。