查看: 34266|回复: 4

[原创] 再说oracle的float类型

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2010-3-13 00:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以前记得遇到过类似的问题。即ORACLE建立了float字段,后来出了莫名其妙的错误。



这次又遇到了,雷人的。我被害惨了,以后谁要在ORACLE里用float类型,我就跟他拼命。



把原理写在这里,供以后查询,我专门在ORACLE里做了个实验,把脚本贴在这里。



Oracle Online Help 说:
FLOAT(b) specifies a floating-point number with binary precision b. The precision b can range from 1 to 126. To convert from binary to decimal precision, multiply b by 0.30103.  

意思是说oracle 的float类型,是按二进制来算的精度,其中精度范围为二进制的1到126,在转化为我们常说的进十进制是,需要X以0.30103



注意它说的是binary pricision而不是decimal precision
你指定3,按照换算公式 INT(3*0.30103)=0,所以小数点后精度为0。
如果需要精度为3,b = CEIL(3 / 0.30103) = 10。

另外。根据我实际测试,ORACLE说的这个精度,还是包含了整数的。

示例脚本:


drop table testdatatype;
--verify the  floating-point number with binary precision
create table testdatatype(
id number(4),
a float(3),  --1/0.30103
b float(4),
c float(6),  --2/0.30103
d float(7),
e float(9),  --3/0.30103
f float(10),
g float(14),  --4/0.30103
h float (15),   --5/0.30103
i float(16),    --6/0.30103
j float(24),    --7/0.30103
k float(27)     --8/0.30103
);
insert into testdatatype values(
1,
999.999
,999.999
,999.999
,999.999
,999.999
,999.999
,999.999
,999.999
,999.999
,999.999
,999.999
);
insert into testdatatype values(
2,
999.555
,999.555
,999.555
,999.555
,999.555
,999.555
,999.555
,999.555
,999.555
,999.555
,999.555
);
insert into testdatatype values(
3,
999.455
,999.455
,999.455
,999.455
,999.455
,999.455
,999.455
,999.455
,999.455
,999.455
,999.455
);
insert into testdatatype values(
4,
999.444
,999.444
,999.444
,999.444
,999.444
,999.444
,999.444
,999.444
,999.444
,999.444
,999.444
);
insert into testdatatype values(
5,
999.111
,999.111
,999.111
,999.111
,999.111
,999.111
,999.111
,999.111
,999.111
,999.111
,999.111
);
insert into testdatatype values(
6,
1942070
,1942070
,1942070
,1942070
,1942070
,1942070
,1942070
,1942070
,1942070
,1942070
,1942070
);

commit;

来看结果。
    ID A B C D E F G H I J K
1 1 1000 1000 1000 1000 1000 1000 1000 1000 1000 999.999 999.999
2 2 1000 1000 1000 1000 1000 999.6 999.56 999.56 999.56 999.555 999.555
3 3 1000 1000 1000 999 999 999.5 999.46 999.46 999.46 999.455 999.455
4 4 1000 1000 1000 999 999 999.4 999.44 999.44 999.44 999.444 999.444
5 5 1000 1000 1000 999 999 999.1 999.11 999.11 999.11 999.111 999.111
6 6 2000000 1900000 1900000 1940000 1940000 1942000 1942100 1942100 1942100 1942070 1942070

注意到最后一排,就算你写的整数。在做INSERT时,也会因为精度问题给你自动四舍五入了。
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
2#
发表于 2010-3-13 00:50 | 只看该作者
这就是牺牲精度来换取速度了。
TOM KYTE的9I & 10G编程艺术:

12.4.2 BINARY_FLOAT/BINARY_DOUBLE 类型的语法和用法
Oracle 10g 引入了两种新的数值类型来存储数据;在Oracle 10g 之前的所有版本中都没有这两种类
型。它们就是许多程序员过去常用的IEEE 标准浮点数。要全面地了解这些数值类型是怎样的,以及它们如
何实现,建议你阅读http://en.wikipedia.org/wiki/Floating-point。需要指出,在这个参考文档中对
于浮点数的基本定义有以下描述(请注意我着重强调的部分):
浮点数是一个有理数子集中一个数的数字表示,通常用于在计算机上近似一个任意的实数。特别是,
它表示一个整数或浮点数(有效数,或正式地说法是尾数)乘以一个底数(在计算机中通常是2)的某个
整数次幂(指数)。底数为2 时,这就是二进制的科学计数法(通常的科学计数法底数为12.)。
浮点数用于近似数值;它们没有前面所述的内置Oracle NUMBER 类型那么精确。浮点数常用在科学计
算中,由于允许在硬件(CPU、芯片)上执行运算,而不是在Oracle 子例程中运算,所以在多种不同类型
的应用中都很有用。因此,如果在一个科学计算应用中执行实数处理,算术运算的速度会快得多,不过你
可能不希望使用浮点数来存储金融信息。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
3#
发表于 2010-3-13 08:00 | 只看该作者

回复 #2 newkid 的帖子

不知道int64和BINARY_DOUBLE 哪个有效数字多,效率高

使用道具 举报

回复
论坛徽章:
5
咸鸭蛋
日期:2012-12-09 22:25:322013年新春福章
日期:2013-02-25 14:51:24复活蛋
日期:2013-03-05 15:00:38马自达
日期:2013-07-31 10:31:17问答徽章
日期:2013-11-20 09:59:28
4#
发表于 2013-4-30 22:11 | 只看该作者
占座

使用道具 举报

回复
论坛徽章:
7
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:532014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11暖羊羊
日期:2015-03-04 14:50:372015年新春福章
日期:2015-03-06 11:57:31秀才
日期:2015-11-12 17:43:40秀才
日期:2015-12-14 15:02:13
5#
发表于 2015-1-8 11:50 | 只看该作者
不错,精

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表