为什么圆形有时会产生额外的数字?

时间:2014-03-31 16:39:24

标签: tsql

有时候,当从数据库中选择汇总数据(通常是AVG())时,我会得到一个重复的小数,例如:

2.7777777777777777

当我将ROUND(AVG(x), 2)应用于该值时,我有时会得到如下结果:

2.7800000000000002

我碰巧知道实际样本有18行SUM(x) = 50.所以这个命令应该是等价的:

SELECT ROUND(50.0/18, 2)

但是,它会产生预期的结果(2.78)。为什么舍入有时会产生聚合函数的错误结果?


为了验证上述结果,我写了query against a dummy table

declare @temp table(
  x float
)

insert into @temp values (1.0);
insert into @temp values (2.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (8.0);
insert into @temp values (9.0);

select round(avg(x), 2),
       sum(x),count(*)
from @temp

我知道gotchas of floating point representation,但这个简单的案例似乎不受这些影响。

2 个答案:

答案 0 :(得分:3)

十进制数并不总是(甚至通常)将1:1映射到浮点的精确表示。

在您的情况下,双精度浮点可以表示的两个最接近的数字是;

这两个数字之间不存在双精度数,在这种情况下,数据库选择较高的值 - 如您所见 - 舍入为2.7800000000000002。

答案 1 :(得分:2)

你的桌子使用花车。当给定浮点数作为参数时,AVG()ROUND()都会返回浮点数。浮子无法准确表示。当您执行ROUND(50.0/18, 2)时,您将NUMERIC(8,6)提供给它DECIMAL(8,6)

尝试声明您的列使用更精确的类型,例如DECIMAL(18,9)。结果应该更加可预测。