讨厌的real和float数据

起因:

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,完全没问题了。

原文地址:https://www.cnblogs.com/chump/p/2640412.html