惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
IT之家
IT之家
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
V
Visual Studio Blog
云风的 BLOG
云风的 BLOG
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
V
V2EX
N
Netflix TechBlog - Medium
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
The Blog of Author Tim Ferriss
量子位
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
月光博客
月光博客
F
Fortinet All Blogs

博客园 - 木人(我现在不是老大)

ERP系统的专业化发展趋势 Svcutil使用点滴 windows server2003企业版64位安装sql server2008企业版64位 读书笔记 UltraGrid(16) 水晶报表使用push模式(2) 水晶报表使用push模式(1) SQL SERVER2000存储过程调试 读书笔记 UltraGrid(15) 读书笔记 UltraGrid(14) 读书笔记 UltraGrid(12) 读书笔记 UltraGrid(11) 读书笔记 UltraGrid(10) 读书笔记 UltraGrid(9) 读书笔记 UltraGrid(8) 读书笔记 UltraGrid(7) 读书笔记 UltraGrid(6) 读书笔记 UltraGrid(5) 读书笔记 UltraGrid(4) 读书笔记 UltraGrid(3)
讨厌的real和float数据
木人(我现在不是老大) · 2012-08-15 · via 博客园 - 木人(我现在不是老大)

起因:

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)