java源码分析(10)- Double(1)
2016-06-14 17:19
579 查看
Double
在研究double前,必须先介绍下IEEE 754算数标准,Double和Float都遵循此标准。
Double遵循此标准中的64位浮点数表示方式。从左到右具体为:
1.第一位为符号部,0表示正,1表示负
2.2~12位为指数部,用以存放具体数值的指数
3.13~64位为尾数部,
其中指数部为11位,可以表示2048个数,为-1023~+1024,因为存在正负号,会导致运算比较困难,故标准中设置了一个偏移值,将指数加上偏移值后得到编码值存储在指数部中,利于计算和比较。其中偏移值为2^(x-1)-1,x为指数部的位数,此处为11,故偏移值为1023.得到的编码值范围为0~2047(其中0(11位全是0)和2047(11位全是1)为特殊情况,下面会提到).
规约数:规约数是指数的编码值(假设为Q),0<Q<2047时,所表示的数,此时尾数的个位将自动补全1.例如,十进制下的15用double存储时,可以分以下几步理解:
1.先将15化为2进制,为1111
2.将1111转化为二进制下的指数形式,为1.111* 2^3,故用double存储时,指数为3,加上偏移值后的指数部存储编码值为1026,尾数部为111(小数点前的1自动补全)
3.double中的值为0100 0000 0010 1110(后面还有48个0)
但光用规约数也会产生问题,例如,只用规约数的话正数最小值为1.0* 2^-1022,这会带来很大麻烦,如1.2*2^(-1022)-1.1*2^(-1022)即0.1*2^(-1022)将用Double表示时将为0,值得连续性也会在此处发生断崖式下降(大于1.0* 2^-1022的数,连续性为2^(-1074)),0也无法表示。故需要引入非规约数。
非规约数:指数部的编码值为0,且尾数部不全为0,此时尾数部的整数位将自动补全0.
当一个数为非规约数时,指数编码值为0,实际指数为-1022(没错,是-1022,不是-1023,需要加1,就是这么规定的),此时,double的连续性将处处相等,都为2^(-1074),并且任何两个double的和差都能用唯一的double值表示。
当指数部编码值为0,尾数部也为0时,double值为0,固0可以有两种表达方式(+0和-0)
当指数部编码为2047,尾部全为0时,表示无穷,尾部不是全为0时,表示NaN
此种设计下的double值比较十分方便,首先比较符号位,为0的一定大于为1的(正数大于负数),若相等,再比较指数位,因为存的编码值都为正数,所以编码值大的数一定大(符号位为0的情况下,为1则结果反一下),若还相等,最后比较尾数位,十分高效。
1.Double 的精度
其中精度由尾数部决定,由于2^52=4503599627370496,长度为16,所以Double绝对能表示15位的数,能表示部分16位的数,所以Double的精度为15~16位。
2.Double的范围
当指数编码值为2046(实际指数为1023),尾数为999999....时,double绝对值值最大,为1.999....* 2^(1023),即2^1024
当指数编码值为0(实际指数为-1022),尾数为2^-52时,double绝对值最小,为2^(-52) * 2^(-1022),即2^(-1074)
3.double的属性
在研究double前,必须先介绍下IEEE 754算数标准,Double和Float都遵循此标准。
Double遵循此标准中的64位浮点数表示方式。从左到右具体为:
1.第一位为符号部,0表示正,1表示负
2.2~12位为指数部,用以存放具体数值的指数
3.13~64位为尾数部,
其中指数部为11位,可以表示2048个数,为-1023~+1024,因为存在正负号,会导致运算比较困难,故标准中设置了一个偏移值,将指数加上偏移值后得到编码值存储在指数部中,利于计算和比较。其中偏移值为2^(x-1)-1,x为指数部的位数,此处为11,故偏移值为1023.得到的编码值范围为0~2047(其中0(11位全是0)和2047(11位全是1)为特殊情况,下面会提到).
规约数:规约数是指数的编码值(假设为Q),0<Q<2047时,所表示的数,此时尾数的个位将自动补全1.例如,十进制下的15用double存储时,可以分以下几步理解:
1.先将15化为2进制,为1111
2.将1111转化为二进制下的指数形式,为1.111* 2^3,故用double存储时,指数为3,加上偏移值后的指数部存储编码值为1026,尾数部为111(小数点前的1自动补全)
3.double中的值为0100 0000 0010 1110(后面还有48个0)
但光用规约数也会产生问题,例如,只用规约数的话正数最小值为1.0* 2^-1022,这会带来很大麻烦,如1.2*2^(-1022)-1.1*2^(-1022)即0.1*2^(-1022)将用Double表示时将为0,值得连续性也会在此处发生断崖式下降(大于1.0* 2^-1022的数,连续性为2^(-1074)),0也无法表示。故需要引入非规约数。
非规约数:指数部的编码值为0,且尾数部不全为0,此时尾数部的整数位将自动补全0.
当一个数为非规约数时,指数编码值为0,实际指数为-1022(没错,是-1022,不是-1023,需要加1,就是这么规定的),此时,double的连续性将处处相等,都为2^(-1074),并且任何两个double的和差都能用唯一的double值表示。
当指数部编码值为0,尾数部也为0时,double值为0,固0可以有两种表达方式(+0和-0)
当指数部编码为2047,尾部全为0时,表示无穷,尾部不是全为0时,表示NaN
此种设计下的double值比较十分方便,首先比较符号位,为0的一定大于为1的(正数大于负数),若相等,再比较指数位,因为存的编码值都为正数,所以编码值大的数一定大(符号位为0的情况下,为1则结果反一下),若还相等,最后比较尾数位,十分高效。
1.Double 的精度
其中精度由尾数部决定,由于2^52=4503599627370496,长度为16,所以Double绝对能表示15位的数,能表示部分16位的数,所以Double的精度为15~16位。
2.Double的范围
当指数编码值为2046(实际指数为1023),尾数为999999....时,double绝对值值最大,为1.999....* 2^(1023),即2^1024
当指数编码值为0(实际指数为-1022),尾数为2^-52时,double绝对值最小,为2^(-52) * 2^(-1022),即2^(-1074)
3.double的属性
public final class Double extends Number implements Comparable<Double> { public static final double POSITIVE_INFINITY = 1.0 / 0.0;//java中将1.0除以0.0设为正无穷 public static final double NEGATIVE_INFINITY = -1.0 / 0.0; public static final double NaN = 0.0d / 0.0;//将0.0/0.0设为一个特殊的非数字的ouble型变量 public static final double MAX_VALUE = 0x1.fffffffffffffP+1023;//最大值为1.7976931348623157e+308 public static final double MIN_NORMAL = 0x1.0p-1022; // 规约数能表示的最小值 public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 所能表示的最小的正数的值为1*(2^-52)*(2^-1022)=4.9e-324 public static final int MAX_EXPONENT = 1023;//指数部最大值为2^1023 public static final int MIN_EXPONENT = -1022;//指数部最小值为2^-1022 public static final int SIZE = 64;//长度为64位,8个字节java中将无穷用1.0/0.0表示,并且所有的无穷都不相等,同时double有一个特殊的属性NaN,表示一个非数字的double型值,用0.0/0.0定义,也可以由两个无穷相除得到,NaN也互不相等。
Double a=Double.POSITIVE_INFINITY; Double b=Double.POSITIVE_INFINITY; Double c=a/b; System.out.println(c);//输出为NaN System.out.println(a==b);//false Double d=Double.NaN; Double e=Double.NaN; System.out.println(d==e);//false System.out.println(d*a);//NaN
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 从源码安装Mysql/Percona 5.5
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序