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

推荐订阅源

U
Unit 42
小众软件
小众软件
Y
Y Combinator Blog
S
SegmentFault 最新的问题
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LangChain Blog
Martin Fowler
Martin Fowler
美团技术团队
B
Blog RSS Feed
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Blog of Author Tim Ferriss
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Hugging Face - Blog
Hugging Face - Blog
D
Docker
G
Google Developers Blog

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

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)