java源码分析(10)- Double(1)

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值