decimal和bigint相除时scale是怎么定义的?
How scale is defined when decimal and bigint are divided?
我有 DECIMAL(19,8) 类型的值 A
- 小数位数是 8
,所以小数点右边存储的小数位数是 8
.
现在,我将 A
除以 B
,其中 B
是 BIGINT
。例如:
SELECT CAST(3 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 0.111111111111111111111111111
,CAST(300 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 11.111111111111111111111111111
,CAST(75003 AS DECIMAL(19, 8)) / CAST(13664400 AS BIGINT) -- 0.005488934750153684025643277
输出值的长度分别为:29
、30
、29
。
谁能告诉我为什么三等分的值的长度不是30
? SQL Server
是如何计算最终结果的比例的?
参数 1:3 AS DECIMAL(19, 8)
参数 2:27 AS DECIMAL (18, 0)
-- 默认精度为 18,默认小数位数为 0(BIGINT
由于类型优先级被转换为 DECIMAL
)
p1 = 19
p2 = 18
s1 = 8
s2 = 0
max precision = (p1 - s1 + s2) + MAX(6, s1 + p2 + 1) -- up to 38
max scale = MAX(6, s1 + p2 + 1)
让我们计算示例 1:
precision: (19 - 8 + 0) + MAX(6, 8 + 18 + 1) = 38
scale: MAX(6, 8 + 18 + 1) = 27
对于所有示例,您将始终获得最大 27 比例。
0.111111111111111111111111111 (27)
11.111111111111111111111111111 (27)
0.005488934750153684025643277 (27)
整个部分只需要必要的数字(1),(2),(1)。
对我来说一切都是完全正确的。
此答案基于 @Paul White
from Decimal Truncation In division
的工作。
这是调用数据类型优先级。
当查询在不同但兼容的类型之间执行某些操作时,必须将其中一个转换为另一种类型,无论是显式转换还是隐式转换。
如果你看Data Type Conversion (Database Engine)
,你会看到Decimal和Bigint之间存在隐式转换。
因此您的查询不需要显式转换。
如果您查看 MSDN 上的 Data Type Precedence (Transact-SQL),您将看到:
- 十进制
- bigint
这意味着decimal比bigint具有更高的优先级,bigint值将转换为decimal。
最后,你的计算将是:
- 3,000... / 27,000...
- 300,000... / 27,000...
- 75003,000... / 27,000...
如果您希望它是 3 / 27
,您必须对 Decimal 值进行显式转换。
我有 DECIMAL(19,8) 类型的值 A
- 小数位数是 8
,所以小数点右边存储的小数位数是 8
.
现在,我将 A
除以 B
,其中 B
是 BIGINT
。例如:
SELECT CAST(3 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 0.111111111111111111111111111
,CAST(300 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 11.111111111111111111111111111
,CAST(75003 AS DECIMAL(19, 8)) / CAST(13664400 AS BIGINT) -- 0.005488934750153684025643277
输出值的长度分别为:29
、30
、29
。
谁能告诉我为什么三等分的值的长度不是30
? SQL Server
是如何计算最终结果的比例的?
参数 1:3 AS DECIMAL(19, 8)
参数 2:27 AS DECIMAL (18, 0)
-- 默认精度为 18,默认小数位数为 0(BIGINT
由于类型优先级被转换为 DECIMAL
)
p1 = 19
p2 = 18
s1 = 8
s2 = 0
max precision = (p1 - s1 + s2) + MAX(6, s1 + p2 + 1) -- up to 38
max scale = MAX(6, s1 + p2 + 1)
让我们计算示例 1:
precision: (19 - 8 + 0) + MAX(6, 8 + 18 + 1) = 38
scale: MAX(6, 8 + 18 + 1) = 27
对于所有示例,您将始终获得最大 27 比例。
0.111111111111111111111111111 (27)
11.111111111111111111111111111 (27)
0.005488934750153684025643277 (27)
整个部分只需要必要的数字(1),(2),(1)。
对我来说一切都是完全正确的。
此答案基于 @Paul White
from Decimal Truncation In division
的工作。
这是调用数据类型优先级。
当查询在不同但兼容的类型之间执行某些操作时,必须将其中一个转换为另一种类型,无论是显式转换还是隐式转换。
如果你看Data Type Conversion (Database Engine) ,你会看到Decimal和Bigint之间存在隐式转换。
因此您的查询不需要显式转换。
如果您查看 MSDN 上的 Data Type Precedence (Transact-SQL),您将看到:
- 十进制
- bigint
这意味着decimal比bigint具有更高的优先级,bigint值将转换为decimal。
最后,你的计算将是:
- 3,000... / 27,000...
- 300,000... / 27,000...
- 75003,000... / 27,000...
如果您希望它是 3 / 27
,您必须对 Decimal 值进行显式转换。