SQL SERVER高人来解释一下decimal(38,12)数据精度的问题

gaowd 2009-05-11 11:31:18
decimal(38,12)数据精度对除法、乘法计算造成精度损失

除法、乘法计算出的小数位数最大为6位? 像单价精度如果超过6位怎么办?SQL SREVER怎么会有这么低级的问题还是有其它设置?

举例说明:

declare @t1 decimal(38,12),@t2 decimal(38,12)

--declare @t1 decimal(28,10),@t2 decimal(28,10)

--declare @t1 float,@t2 float

set @t1 = 3.00000000001

set @t2 = 100.00000000001

select @t2/@t1

select @t2 + @t1

select @t2 * @t1

计算结果为:

decimal(38,12)

除法 33.333333
加法 103.00000000002
乘法 300.000000





 
...全文
1458 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
等不到来世 2009-05-11
  • 打赏
  • 举报
回复
decimal型表达式 e1(精度为 p1,小数位数为 s1)和表达式 e2(精度为 p2,小数位数为 s2),
它们运算结果的位数有如下算法:


运算 结果精度 结果小数位数
----------------------------------------------------------------
e1 + e2 max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2)
e1 - e2 max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2)
e1 * e2 p1 + p2 + 1 s1 + s2
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1-s1, p2-s2) max(s1, s2)



在本例中,当e1/e2时,结果小数位数取 max(6,s1+p2+1),但s1+p2+1>38,所以为了不截断整数部分,系统取了6.
这就是为什么你把总精度设得那么高,小数部分反而总是6的原因。
等不到来世 2009-05-11
  • 打赏
  • 举报
回复 1
改小一下总精度的值即可。
declare @t1 decimal(25,12),@t2 decimal(25,12) 

set @t1 = 3.00000000001

set @t2 = 100.00000000001

select @t2/@t1 --33.3333333332255

select @t2 + @t1 --103.000000000020

select @t2 * @t1 --300.00000000103
gaowd 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qianjin036a 的回复:]
因为MSSQL在运算时不单单要考虑你的
set @t1 = 3.00000000001
set @t2 = 100.00000000001
还要考虑你可能的
set @t1 =99999999999999999999999999.00000000001
set @t2 = 100.00000000001
[/Quote]所以说这个问题低级,SQL SERVER应该能自动区分是整数部分还是小数部分,不能总体计算
JonasFeng 2009-05-11
  • 打赏
  • 举报
回复
学习
-晴天 2009-05-11
  • 打赏
  • 举报
回复
因为MSSQL在运算时不单单要考虑你的
set @t1 = 3.00000000001
set @t2 = 100.00000000001
还要考虑你可能的
set @t1 =99999999999999999999999999.00000000001
set @t2 = 100.00000000001

-晴天 2009-05-11
  • 打赏
  • 举报
回复
结果精度和小数位数的绝对最大值为 38。当结果精度大于 38 时,相应的小数位数会减少,以避免结果的整数部分被截断。
你用精度都为 decimal(38,12) 的两数相乘除,其结果精度都远大于38,因此小数位数被截断.
-晴天 2009-05-11
  • 打赏
  • 举报
回复
当结果精度大于 38 时,相应的小数位数会减少,以避免结果的整数部分被截断。
gaowd 2009-05-11
  • 打赏
  • 举报
回复
了解了
幸运的意外 2009-05-11
  • 打赏
  • 举报
回复
楼主朋友并不是SQL的错误,而是您给出的数据的精度和长度没有必要按照38长度,12位小数这样的精度来显示。所以系统就在当次计算时去最大长度和最大位数的书的长度和精度来对结果进行计算。所以出现了以上结果。但是在2个数字相乘时,由于实际结果小数位数已经超过了规定值被截断了。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧