oracle比较浮点与整数,float与double的范围和精度 不同类型和0比较

本文详细介绍了浮点数(float和double)的范围和精度,以及Oracle数据库中Number类型的特性和使用。浮点数的指数和尾数位决定了它们的表示范围和精度,而Oracle的Number类型则提供了极大的数值存储灵活性,可表示极小到极大的数值。在编程中,需要注意浮点数的精度问题,避免直接使用等于或不等于进行比较,而应采用误差范围判断。此外,还讨论了布尔、整型和指针变量与零值比较的最佳实践。
摘要由CSDN通过智能技术生成

1. 范围

float和double的范围是由指数的位数来决定的。

float的指数位有8位,而double的指数位有11位,分布如下:

float:

1bit(符号位) 8bits(指数位) 23bits(尾数位)

double:

1bit(符号位) 11bits(指数位) 52bits(尾数位)

于是,float的指数范围为-127~+128,而double的指数范围为-1023~+1024,并且指数位是按补码的形式来划分的。

其中负指数决定了浮点数所能表达的绝对值最小的非零数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。

float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。

2.  精度

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。

float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;

double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

3.Oracle中Number类型

在Oracle中Number类型可以用来存储0,正负定点或者浮点数,可表示的数据范围在

1.0 * 10(-130) —— 9.9...9 * 10(125) {38个9后边带88个0}

的数字,当Oracle中的数学表达式的值>=1.0*10(126)时,Oracle就会报错。

Number的数据声明如下:

表示        作用        说明

Number(p, s)        声明一个定点数        p(precision)为精度,s(scale)表示小数点右边的数字个数,精度最大值为38,

Number(p)        声明一个整数        相当于Number(p, 0)

Number        声明一个浮点数        其精度为38,要注意的是scale的值没有应用,也就是说scale的指不能简单的理解为0,或者其他的数。

定点数的精度(p)和刻度(s)遵循以下规则:

当一个数的整数部分的长度 > p-s 时,Oracle就会报错

当一个数的小数部分的长度 > s 时,Oracle就会舍入。

当s(scale)为负数时,Oracle就对小数点左边的s个数字进行舍入。

当s > p 时, p表示小数点后第s位向左最多可以有多少位数字,如果大于p则Oracle报错,小数点后s位向右的数字被舍入

4.验证

create or replace function  func_test(p_type number) return number

is

/*

功能:基于警度图数据同步

*/

l_cnt number;

begin

select p_type into l_cnt from dual;

return l_cnt;

end func_test;

/

show err;

5.结论

number 的总长度是40位,其中可能包括:小数点,负号位。

select to_char(func_test(-987.1234567891234567891234567891234567891234)) from dual;

-987.12345678912345678912345678912345679   //包括小数点及负号位共40位

select to_char(func_test(9876.1234567891234567891234567891234567891234)) from dual;

9876.12345678912345678912345678912345679   //4位整数+小数点+35位小数=40位

select to_char(func_test(987.1234567891234567891234567891234567891234)) from dual;

987.123456789123456789123456789123456789   //3位整数+小数点+36位小数=40位

select to_char(func_test(1234567891234567891234567891234567891234)) from dual;

1234567891234567891234567891234567891234   //40位整数

select to_char(func_test(12345678912345678912345678912345678912345)) from dual;

1.2345678912345678912345678912345679E+40   //41位时精度发生丢失

1.2345678912345678912345678912345679×10^40 即 12345678912345678912345678912345678900000

浮点变量与零值比较【规则4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较。千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“> =”或“ <=”形式。假设浮点变量的名字为x,应当将if   (x   ==   0.0)   //隐含错误的比较转化为if   ((x> =-EPSINON)   &&   (x <=EPSINON))其中EPSINON是允许的误差(即精度)。

EPSINON的值应大于你所用编译器的float(double)的精度1到2个数量级。千万不能等于甚至小于浮点精度,否则就跟直接比较一样了。这个问题有必要搞懂。许多论坛上经常有人问,为什么float或double型不能用来控制switch流程?弄懂本帖问题后,就不会再提那样的傻问题了。

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

以下摘自《林锐-高质量c++c编程指南》/*   ----------------------------------------------------------------------------   */

if语句是C++/C语言中最简单、最常用的语句,然而很多程序员用隐含错误的方式写if语句。本节以“与零值比较”为例,展开讨论。4.3.1布尔变量与零值比较【规则4-3-1】不可将布尔变量直接与TRUE、FALSE或者1、0进行比较。根据布尔类型的语义,零值为“假”(记为FALSE),任何非零值都是“真”(记为TRUE)。TRUE的值究竟是什么并没有统一的标准。例如Visual   C++将TRUE定义为1,而Visual   Basic则将TRUE定义为-1。假设布尔变量名字为flag,它与零值比较的标准if语句如下:if   (flag) //表示flag为真if   (!flag) //表示flag为假其它的用法都属于不良风格,例如:if   (flag   ==   TRUE)

if   (flag   ==   1   )

if   (flag   ==   FALSE)

if   (flag   ==   0)

4.3.2整型变量与零值比较【规则4-3-2】应当将整型变量用“==”或“!=”直接与0比较。假设整型变量的名字为value,它与零值比较的标准if语句如下:if   (value   ==   0)

if   (value   !=   0)不可模仿布尔变量的风格而写成if   (value) //会让人误解value是布尔变量if   (!value)

4.3.3浮点变量与零值比较【规则4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较。千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“> =”或“ <=”形式。假设浮点变量的名字为x,应当将if   (x   ==   0.0)   //隐含错误的比较转化为if   ((x> =-EPSINON)   &&   (x <=EPSINON))其中EPSINON是允许的误差(即精度)。4.3.4指针变量与零值比较【规则4-3-4】应当将指针变量用“==”或“!=”与NULL比较。指针变量的零值是“空”(记为NULL)。尽管NULL的值与0相同,但是两者意义不同。假设指针变量的名字为p,它与零值比较的标准if语句如下:if   (p   ==   NULL) //   p与NULL显式比较,强调p是指针变量if   (p   !=   NULL)不要写成if   (p   ==   0)   //容易让人误解p是整型变量if   (p   !=   0)或者if   (p) //容易让人误解p是布尔变量if   (!p)

4.3.5对if语句的补充说明有时候我们可能会看到if   (NULL   ==   p)这样古怪的格式。不是程序写错了,是程序员为了防止将if   (p   ==   NULL)误写成if   (p   =   NULL),而有意把p和NULL颠倒。编译器认为if   (p   =   NULL)是合法的,但是会指出if   (NULL   =   p)是错误的,因为NULL不能被赋值。程序中有时会遇到if/else/return的组合,应该将如下不良风格的程序if   (condition)

return   x;

return   y;改写为if   (condition)

{

return   x;

}

else

{

return   y;

}或者改写成更加简练的return   (condition   ?   x   :   y);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值