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