2011-10-10 80 views
0

我正在使用SQL Server 2005.并且我正在使用ROUND T-SQL函数舍入十进制列值。但看起来四舍五入的值是不正确的。SQL Server舍入问题

PRINT ROUND(1890.124854, 2) => 1890.120000 

如图ROUND函数将返回1890.12其中因为它应该是1890.13。有没有人遇到过这种情况,应该采用正确的四舍五入方式,以便获得期望值1890.13 ..?

谢谢。

+4

为什么应该是1890.13?你要求它舍入到小数点后两位,而且它的确如此 - .xx4向下舍入,而不是向上。 –

+0

好的..所以当我们指定长度为2时,它只会看到舍入的第三个小数点值吗? –

+0

是的,这就是所有这些舍入函数的定义。 –

回答

6

ROUND()按照它的意图工作。你指定四舍五入到小数点后两位,这就是你得到的。

返回数值,舍入到指定的长度或精度。

舍入意味着5位或5位以上的数字上升到最近,小于5位到最近。

所以,

PRINT ROUND(1890.125000, 2) 

产生1890.130000

PRINT ROUND(1890.124999, 2) 

产生1890.120000

2

你的四舍五入问题与SQL Server所使用的舍入算法。我相信SQL Server使用“Round to Even”(有时称为Banker's Rounding)算法。 在银行家的舍入中,如果数字右侧的最低有效位数小于5,则数字将被舍入,如果其右侧的最低有效位数大于5,则该数字将被舍入。 如果它右侧的最低有效数字等于五,那么五的左边的数字会四舍五入到最接近的偶数。

在你的1890.124854的例子中,由于四舍五入开始于最右边的数字并且向左工作,8使得它左边的4被四舍五入为5.这五个具有偶数( 2)在它的左边,因为它已经是平坦的了,所以它就不存在了。因此,舍入到小数点后两位应该产生1890.12。 然而,如果你的例子是1890.134854,那么随着舍入从右到左工作,8轮舍入4到5,然后5到5的下一个舍入到4的下一个偶数。结果四舍五入到小数点后两位应该产生1890.14。

理论是1890.125既不接近1890.12或1890.13。它恰好在两者之间。因此,总是将5位左边的每个数字四舍五入,会产生不希望的向上偏差,这会导致计算偏向于人为的较高结果。这种偏差在复杂的计算中变得更加夸张,或者涉及多次迭代的那些偏差,其中五次可能会遇到无数次最不重要的数字。但是,在一般计算中,5左侧的数字在统计上可能与偶数相同。正因为如此,舍入到偶数导致计算的统计悬停接近圆整数的真正平均值。

现在,几乎所有的事情都使用这种“从头到尾”的算法。很多年前,我曾经用一种没有的编程语言来开发。它使用了更加“传统”的四舍五入,即5号左边的所有东西都被四舍五入,无论是奇数还是偶数。我们遇到了上面提到的偏置问题。

+1

好吧,所以我刚刚看到了这一点,并且想对我的SQL Server 2014实例(12.0.4100.1)中使用的舍入算法发表评论。它不使用银行家的舍入算法,但如果重要数字是5,总是舍入。我正在进一步研究这个,看看我能做些什么来改变它。 –