分享
 
 
 

Java的double类型探索.

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

一.double类型的存储表示

Java的浮点类型表示完全按照IEEE754标准(Standards of IEEE 754 floating point numbers),有兴趣可以上IEEE标准网站(www.ieee.org)查阅.该标准的内容基本上描述了浮点类型的存储格式(Storage Layout),下面我从中总结几段,来概括该标准,详细信息请查阅标准原文.

1.什么是浮点数.

计算机上表达实数有两中方法:定点表示(fixed-point)和浮点表示(floating-point).定点表示法就是在现有的数字中间的某个位置固定小数点,整数部分和小数部分的表示和一个普通整数的表示法没什么两样.例如,我们的数字长度为4,小数点位于中间,那么你可以表示10.28,也可以表示00.01,与这种方法性质类似的定点表示还有使用分数的形式.定点数的固定窗口形式使得他既不能够表示非常大的数又不能表示非常小的数.并且当除法发生时,大量 的精度丢失.

浮点数采用科学计数法的形式来表示实数.例如123.456可以表示成1.23456×102.相对于定点数的固定窗口(fixed Window)的限制,它采用的是浮动窗口(sliding window),因此可以表示较大精度范围的一个实数.

2.存储布局(Storage Layout)

所谓的存储布局就是一个浮点数在内存中如何表示.我们知道浮点数有float和double,前者是4个字节也就是32位,后者是8个字节也就是64位.布局分别为:

符号 指数 小数部分 偏移附加(bias)

单精度 1[31] 8[30-23] 23[22-00] 127

双精度 1[63] 11[62-52] 52[51-00] 1023

中括号内为位的编号范围,外面为该部分所占有的位的数量.偏移附加不属于位表示的内容,是一个常量,稍后解释.

符号只有一位:0-表示正数 1-表示负数

指数部分:用指数部分的值(8位/11位,unsigned)的值 减去 偏移附加 得到该数实际的指数 例如值为200,实际指数为73=200-127.对于双精度的double来说常量bias=1023

尾数:尾数是什么?对于一个科学计数法来讲,形式象这样的 L.M×BE,那么这个L.M就是所谓的尾数(mantisa).它由一个起始位和一个小数部分组成.举个例子,5可以用科学计数法表示成不同形式:

5*100

0.5*101

50*10-1

那么我们引进一个概念,规范化形式(normalized form)和非规范化形式(denormalized form).我们定义规范化形式为小数点位于第一个不为0的数字后面的表达形式为规范化形式,因此上面的第一种形式为规范化形式,其他的为非规范化形式,Java中的浮点表示完全按照这个标准,只有两种形式规范化形式:1.f 和 非规范化形式 0.f .

那么,对于我们的位布局来说,选用底数为2的话,只有一个数字是非零的,那就是1.所以我们的隐含起始数字可以不用占用一个位,因为除了0就只能是1,具体的隐含规则,稍后展示.

3.表示的意义.

对应于上面的表格,每一个区域对应的值的范围所表示的浮点数的意义:

符号位s 指数位e 小数位f 所表示的意义v

0 00..00 00..00 +0

0 00..00 00..01

:

11..11 正的非规范实数,计算方法v=0.f × 2(-b+1)

0 00..01

:

11..10 XX..XX 正的规范化实数,计算方法v=1.f × 2(e-b)

0 11..11 00..00 正的无穷大

0 11..11 00..01

:

01..11 无意义的非数字SNAN

0 11..11 10..00

:

11..11 无意义的非数字QNAN

其中b=127(float)/b=1023(double),SNAN表示无效运算结果,QNAN表示不确定的运算结果,都是无意义的.

如果把符号位s改成1,那么就全部都是负数的含义,其他意义和这相同.

另外我们看到,对于无意义的数字是指数部分为全1时,也就是说这里有很多种组合都是无意义的非数字,而我们的Java中,判断一个数字是否是NAN的做法相当简单

static public boolean isNaN(double v) {

return (v != v);

}

从这里可以看出来,虚拟机对于double类型的数据比较时,肯定是先做了指数值的判定,发现不是全1时才作内存的逐位比较.当然这是我得推测,真像不知道是否如此.

再另外,我们'现在十分清楚,double类型所能表示的最小值就是它的值之间的距离,也就是我们所说的精度,数字按这种精度向整数"1阶梯式的累加时,正好不能和1完全匹配,换句话说,1不是最小值(精度/距离)的整数倍.因此如果你设置变量 double d = 0.1;而结果不会是0.1,因为无法表示0.1;

二.怎么查看double类型的存储结构?

我们很清楚Java的Double类型提供一个函数叫做doubleToLongBits函数,这个函数的其实很简单,我们知道,long类型和double类型都是64位的,他们的内存大小一样,这个函数的做法就是把double对应的内存结构复制到同样大小的long类型变量的内存结构中.返回这个long值.因为Java不支持对double类型做位运算,因此:

1.该函数不可能用Java语言完成,所以他是JNI实现

2.我们利用对long类型的位运算可以把该内存结构打印出来查看.

/**

* 测试

*/

public static void main(String[] args){

myTest t = new myTest();

double d = 0.1d;

long l = Double.doubleToLongBits(d);

System.out.println(t.getLongBits(l));

}

/**

* 得到常整数的bit位表示字符串

* @param a

* @return

*/

public String getLongBits(long a){

//8个字节的字节数组,读出来

byte[] b = new byte[8];

for(int i=7;i>=0;i--){

b[i] = (byte)(a&0x000000FF);

a = a>>8;

}

return this.byte2hex(b); //调用下面一个函数

}

/**

* 字节数组转换成字符串

* @param b

* @return

*/

public static String byte2hex(byte[] b){

StringBuffer sb=new StringBuffer();

String stmp="";

for(int n=0;n<b.length;n++){

stmp=(Integer.toHexString(b[n]&0XFF));

if(stmp.length()==1){

//不足两位的末尾补零

sb.append("0"+stmp);

} else{

sb.append(stmp);

}

if(n<b.length-1){

//":"作为分割符

sb.append(":");

}

}

return sb.toString().toUpperCase();

}

0.1打印出来的内存结果是:

3F:B9:99:99:99:99:99:9A

我们恢复一下和第一节的表示意义对照表对照一下:

0 01111111011 1001.....1010

有兴趣的话,可以那科学计算器按照第一节的规则计算一下它的值,哦,正好就是我们通过System.out.println(d)打印的结果.

好了.这就是全部,我不认为我把问题表达的很清楚,因为我的总觉得文字和我的想法还是有一点距离,大概这就是表达能力吧.如果你不至于糊涂,我将很高兴.

曹想华 完成于2005-3-27 15:38:25

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有