qey

Atitude is Everything.-- 关注C/C++,关注Linux(Unix) ,关注网络。 Better Late Than Never.
随笔 - 4, 文章 - 13, 评论 - 7, 引用 - 0
数据加载中……

浮点数在内存中表示

little-endian 类型的x86 cpu内存数据排列顺序:低byte ->低地址

double float 浮点数在内存中表示:

double浮点数是用qword 表示的,也就是8个bytes,4个words;第一个bit表示符号;紧接着的11个bits表示幂,幂偏移量为-(2^10-1)(^在C中为异或符),也就是-1023;后面的52bits表示保存精度,实际上精度为53bits,第1bits默认为1,并没有在这里体现出来。

从高地址到低地址内存中,数据排列格式如下(该double数据地址为+0byte的地址):

地址 +7               +6                    +5                       +4  
内容 SEEE EEEE EEEE MMMM MMMM MMMM MMMM MMMM
       MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM
地址 +3                 +2                  +1                   +0

先看看13.15在内存是如何存放:
首先13.15表示成二进制形式;

13 -> 0x0D ->1101(B) 计算方法也就是微机原理学过的除于2取余数倒排列;
.15 ->  计算方法是乘以2,取进位顺排列;.0010 0011 0011…………
 0.15*2
=0.3(*2)   进位0
=0.6(*2)   进位0
=1.2(*2)   进位1
=0.4(*2)   进位0
=0.8(*2)   进位0
=1.6(*2)   进位1
=1.2(*2)   进位1
=0.4(*2)   进位0
=0.8(*2)   进位0
………………
最后那一位要看后面的实际排列;
转换为二进制为:
1101. 0010 0110 0110 0110 …………
移动小数点直到小数点前面只有一个1。
1.1010 0100 1100 1100 1100 …………
移动了3为,幂为3,加上偏移量1023,就是1026,这个也就是E中的值;
那么在M中保存的数据就是:
1010 0100 1100 1100 1100 …………
最后结果得到:
地址 +7              +6              +5              +4   
内容 0100 0000 0010 1010 0100 1100 1100 1100 
        1100 1100 1100 1100 1100 1100 1100 1101
地址 +3              +2              +1              +0

最后面为什么变成1101呢?由于紧跟其后的是数据1100最前的1;精度的进位,类似四舍五入。
十六进制就是:0x40 2A 4C CC CC CC CC CD    (在栈中数据形式)
0012FF70  CD CC CC CC  吞烫
0012FF74  CC 4C 2A 40  蘈*@

double* aa=new double; &aa =0x00491DA0;*aa =13.15;(在堆中数据形式)
00491DA0  CD CC CC CC  吞烫
00491DA4  CC 4C 2A 40  蘈*@

*******************************************************************

-13.2(double)
0012FF70  66 66 66 66  ffff
0012FF74  66 66 2A C0  ff*@

如何看出内存的double数据是多少呢?
例如上面的-13.2 的十六进制数
C0             2A              66             66        66 66 66 66
1100 0000 0010 1010 0110 0110 0110 0110 0110 ……
二进制就是如上:
符号为看出是负值;幂值由100 0000 0010(也就是10进制的1026)加上偏移量-1023,结果3得到。
1.1010 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110
乘幂移位后就是:
1101.0 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110
再将上面的二进制转换为
1101 ->
1*2^3 +1*2^2 +0*2^1 +1*2^0 =13;
.0 0110 0110 0110 …… ->
0*2^(-1) +0*2^(-2) +1*2^(-3) +1*2^(-4) +0*2^(-5)…… =.20000???
也就是13.2,再加上负号就是 -13.2。

float情况类似,只是float占用4byte,符号位1bit,幂用8bits表示,偏移量-127;其他基本类同。

如果想详细了解,请参考:
http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF

posted on 2008-11-14 00:12 无声无色 阅读(2173) 评论(0)  编辑 收藏 引用 所属分类: 语言基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理