Sql 十进制类型的@value和FLOOR(@value)之差为0

Sql 十进制类型的@value和FLOOR(@value)之差为0,sql,sql-server,decimal,floor,Sql,Sql Server,Decimal,Floor,这里的很多答案都说使用 SELECT @value - FLOOR(@value) 获取数字的小数部分。有关示例,请参见或 当我这样做的时候,我得到了我认为是奇怪的行为。 DECLARE @test DECIMAL(38, 8) SET @test = 123.05468800 SELECT @test - FLOOR(@test) Result: 0 我能行 SELECT 123.05468800 - FLOOR(123.05468800) Result: 0.05468800 我

这里的很多答案都说使用

SELECT @value - FLOOR(@value)
获取数字的小数部分。有关示例,请参见或

当我这样做的时候,我得到了我认为是奇怪的行为。

DECLARE @test DECIMAL(38, 8)
SET @test = 123.05468800

SELECT @test - FLOOR(@test)

Result: 0
我能行

SELECT 123.05468800 - FLOOR(123.05468800)

Result: 0.05468800
我可以将
@test
的类型更改为
FLOAT
,它就可以工作了。同样
FLOOR(@test)
按预期返回
123

我想这与十进制类型的精度有关,但在这个主题上,这是非常稀疏的

发生了什么事?为什么我得不到小数部分
.05468800
?我应该做什么或者用什么来得到这个

DECLARE @test DECIMAL(38, 8), @test2 DECIMAL(28, 8)
SET @test = 123.05468800
SET @test2 = 123.05468800

SELECT 
    @test as test, 
    FLOOR(@test) AS floortest, 
    @test-FLOOR(@test) AS broken, 
    @test - CAST(FLOOR(@test) AS DECIMAL(38, 8)) AS fixed
INTO gbntest;

SELECT 
    @test2 as test, 
    FLOOR(@test2) AS floortest, 
    @test-FLOOR(@test2) AS working
INTO gbntest2;

SELECT 
    123.05468800 as test,
    FLOOR(123.05468800) as floortest,
    123.05468800 - FLOOR(123.05468800) as working
INTO gbntest3;

SELECT * FROM INFORMATION_SCHEMA.COLUMNS C WHERE C.TABLE_NAME LIKE 'gbntest%';
DROP TABLE gbntest;
DROP TABLE gbntest2;
DROP TABLE gbntest3;
注gbntest的中间2为
十进制(38,0)

但是,对于常量或
decimal(28,8)
则有效。
(29,8)
(30,8)

但是,使用
(31,8)
你会得到
(38,7)

MSDN描述了原因

                precision                                 scale
 ...
 e1 - e2        max(s1, s2) + max(p1-s1, p2-s2) + 1       max(s1, s2)
对于(31,8),精度为(40,8)


(40,8)
应下调至
(38,6)
。所以我把我的计算放在了某个地方:-)但是我希望你能得到这个想法…

非常好!显然,我没有深入研究精确行为!啊,我明白了。关键是链接页面底部的脚注。“…精度[有]绝对最大值38。当结果精度大于38时,…刻度将减小。”所以现在我的问题是,在这种情况下,为什么下限不返回十进制(38,8)?表示它应该具有与输入相同的结果类型。
max(8,0) + max(31-8, 31-0) + 1 -> 8 + 31 + 1 -> 40
max(8,0) -> 8