起因:
declare @w1 as real,@h1 as real
set @w1=390
set @h1=1865
select @w1*@h1/1000000.00
这个结果是什么?答案是:0.72735
没错。你看到的是0.72735,计算器算也是这个结果。
如果我们使用round四舍五入,如:select ROUND(@w1*@h1/1000000.00,4),结果想当然是:0.7274
错了。结果是:0.72729999999999995,约等于0.7273!
怪了,为什么会这样?
这个与浮点数的存储及机制有关!
看sql server2000的帮助:
用于表示浮点数字数据的近似数字数据类型。浮点数据为近似值;并非数据类型范围内的所有数据都能精确地表示。
也就是由于浮点数是按科学计数法表示,以便占用较小的空间,所以在转换为二进制的时候,到某位总要舍入或进位,导致浮点数保存有的比原始值大,而有的比原始值小。所以我们看到的0.72735,实际上保存的并不是这个值;
select cast(@w1*@h1/1000000.00 as decimal(18,10))
结果是:0.7273499966,所以导致round的时候舍入为:0.7273;
如何解决round问题呢?
1.两次舍入
select round(ROUND(@w1*@h1/1000000.00,6),4)
2.加一个误差值,如0.000001
select ROUND(@w1*@h1/1000000.00+0.000001,4)
个人觉得,如果对于数值结算的精度要求比较高,还是要用decimal数据类型,虽然存储空间增大了一些,但在计算过程中就少了许多烦人的问题。况且现在的存储介质能值几个钱呢?
看这个:
declare @w1 as decimal(18,4),@h1 as decimal(18,4)
set @w1=390
set @h1=1865
select @w1*@h1/1000000.00
select ROUND(@w1*@h1/1000000.00,4)
结果就是:0.7274000,完全没问题了。