可以准确划分和重构哪些SQL Server数据类型

时间:2012-08-21 05:37:52

标签: sql-server

考虑下面的T-SQL代码。我想为a,b,c分配10个单位,根据a,b,c的当前值按比例分配。

对于这种情况,

select @a + @b + @c

计算后正好是预期的10。

但是,在我的客户端应用程序中,值从存储过程返回为

4.72222222222222, 4.72222222222222, 0.555555555555556

当汇总在一起时,他们来到9.999999999999996

粗略地说,问题似乎是在4.72222222222222值的两端都缺少2,如果我手动添加它们,结果= 10正如预期的那样。

相反,如果0.555555555555556少了一个,例如0.55555555555556,则总和结果= 10.

有人能建议如何优雅地处理这个问题吗?每个结果的精确度并不重要,但重要的是它们总是归结为原始@adjustby

declare @totalOwned float
declare @adjustby float
declare @a float
declare @b float
declare @c float

set @adjustby = 10
set @a = 85
set @b = 85
set @c = 10

set @totalOwned = @a + @b + @c 

select @a = @adjustby * (@a/@totalOwned)
select @b = @adjustby * (@b/@totalOwned)
select @c = @adjustby * (@c/@totalOwned)

select @a + @b + @c,@a,@b,@c

2 个答案:

答案 0 :(得分:0)

这与SQL Server无关。这是IEEE浮点数的正常行为。它们是近似值而不是精确值 - 例如,请阅读floating-point-guide

您可以通过舍入最终结果来获得预期结果,但这也不能保证正确的结果。如果您需要返回原始结果,则需要避免使用浮点数。

答案 1 :(得分:0)

使用float数据类型代替decimal。声明小数:

declare @d decimal(p,s)

p是小数点左侧和右侧可存储的精度或总小数位数。

s是可以存储在小数点右侧的小数位数或小数位数。

所以要存储4.72222222222222,您至少需要decimal(15,14)。 15位小数,其中14位小数点后面。