|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你说是sun公司对她研究的透还是微软?针对自己工具开发的.net性能上肯定会站上风的。一.double范例的存储暗示
Java的浮点范例暗示完整依照IEEE754尺度(StandardsofIEEE754floatingpointnumbers),有乐趣能够上IEEE尺度网站(www.ieee.org)查阅.该尺度的内容基础上形貌了浮点范例的存储格局(StorageLayout),上面我从中总结几段,来归纳综合该尺度,具体信息请查阅尺度原文.
1.甚么是浮点数.
盘算机上表达实数有两中办法:定点暗示(fixed-point)和浮点暗示(floating-point).定点暗示法就是在现有的数字两头的某个地位流动小数点,整数部分和小数部分的暗示和一个一般整数的暗示法没甚么两样.比方,我们的数字长度为4,小数点位于两头,那末你能够暗示10.28,也能够暗示00.01,与这类办法性子相似的定点暗示另有利用分数的情势.定点数的流动窗口情势使得他既不克不及够暗示十分年夜的数又不克不及暗示十分小的数.而且当除法产生时,大批的精度丧失.
浮点数接纳迷信计数法的情势来暗示实数.比方123.456能够暗示成1.23456×102.相对定点数的流动窗口(fixedWindow)的限定,它接纳的是浮动窗口(slidingwindow),因而能够暗示较年夜精度局限的一个实数.
2.存储结构(StorageLayout)
所谓的存储结构就是一个浮点数在内存中怎样暗示.我们晓得浮点数有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
那末我们引进一个观点,标准化情势(normalizedform)和非标准化情势(denormalizedform).我们界说标准化情势为小数点位于第一个不为0的数字前面的表达情势为标准化情势,因而下面的第一种情势为标准化情势,其他的为非标准化情势,Java中的浮点暗示完整依照这个尺度,只要两种情势标准化情势:1.f和非标准化情势0.f.
那末,关于我们的位结构来讲,选用底数为2的话,只要一个数字长短零的,那就是1.以是我们的隐含肇端数字能够不必占用一个位,由于除0就只能是1,详细的隐含划定规矩,稍后展现.
3.暗示的意义.
对应于下面的表格,每个地区对应的值的局限所暗示的浮点数的意义:
标记位s指数位e小数位f所暗示的意义v
000..0000..00+0
000..0000..01
:
11..11正的非标准实数,盘算办法v=0.f×2(-b+1)
000..01
:
11..10XX..XX正的标准化实数,盘算办法v=1.f×2(e-b)
011..1100..00正的无量年夜
011..1100..01
:
01..11偶然义的非数字SNAN
011..1110..00
:
11..11偶然义的非数字QNAN
个中b=127(float)/b=1023(double),SNAN暗示有效运算了局,QNAN暗示不断定的运算了局,都是偶然义的.
假如把标记位s改成1,那末就全体都是正数的寄义,其他意义和这不异.
别的我们看到,关于偶然义的数字是指数部分为全1时,也就是说这里有良多种组合都是偶然义的非数字,而我们的Java中,判别一个数字是不是是NAN的做法相称复杂
staticpublicbooleanisNaN(doublev){
return(v!=v);
}
从这里能够看出来,假造机关于double范例的数据对照时,一定是先做了指数值的判断,发明不是全1时才作内存的逐位对照.固然这是我得推想,真像不晓得是不是云云.
再别的,我们如今非常分明,double范例所能暗示的最小值就是它的值之间的间隔,也就是我们所说的精度,数字按这类精度向整数"1门路式的累加时,恰好不克不及和1完整婚配,换句话说,1不是最小值(精度/间隔)的整数倍.因而假如你设置变量doubled=0.1;而了局不会是0.1,由于没法暗示0.1;
二.怎样检察double范例的存储布局?
我们很分明Java的Double范例供应一个函数叫做doubleToLongBits函数,这个函数的实在很复杂,我们晓得,long范例和double范例都是64位的,他们的内存巨细一样,这个函数的做法就是把double对应的内存布局复制到一样巨细的long范例变量的内存布局中.前往这个long值.由于Java不撑持对double范例做位运算,因而:
1.该函数不成能用Java言语完成,以是他是JNI完成
2.我们使用对long范例的位运算能够把该内存布局打印出来检察.
/**
*测试
*/
publicstaticvoidmain(String[]args){
myTestt=newmyTest();
doubled=0.1d;
longl=Double.doubleToLongBits(d);
System.out.println(t.getLongBits(l));
}
/**
*失掉常整数的bit位暗示字符串
*@parama
*@return
*/
publicStringgetLongBits(longa){
//8个字节的字节数组,读出来
byte[]b=newbyte[8];
for(inti=7;i>=0;i--){
b[i]=(byte)(a&0x000000FF);
a=a>>8;
}
returnthis.byte2hex(b);//挪用上面一个函数
}
/**
*字节数组转换成字符串
*@paramb
*@return
*/
publicstaticStringbyte2hex(byte[]b){
StringBuffersb=newStringBuffer();
Stringstmp="";
for(intn=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(":");
}
}
returnsb.toString().toUpperCase();
}
0.1打印出来的内存了局是:
3F:B9:99:99:99:99:99:9A
我们恢复一下和第一节的暗示意义对比表对比一下:
0011111110111001.....1010
有乐趣的话,能够那迷信盘算器依照第一节的划定规矩盘算一下它的值,哦,恰好就是我们经由过程System.out.println(d)打印的了局.
好了.这就是全体,我不以为我把成绩表达的很分明,由于我的总以为笔墨和我的设法仍是有一点间隔,也许这就是表达才能吧.假如你不至于懵懂,我将很乐意.
曹想华完成于2005-3-2715:38:25
到时我们不用学struts,不用学spring,不用学Hibernate,只要能把jsf学会了,完全可以替代所有的框架,包括AJAX,都知道AJAX并不是新技术,虽说我没深入学习jsf但我认为jsf应该已经能通过其它技术替代AJAX,实现无缝刷新。 |
|