今天在使用union联合体的时候无意中发现double的内存模型和古怪,o(︶︿︶)o 唉,只能说自己当时计算机组成没有学好,
float 1 8 23 32
double 1 11 52 64
更确切的说是自己当时没怎么学懂,好在今天解决了它。
首先发一个代码(问题的引出):
断点调试:
查看memory:
由此图大家可以看到double类型的b成员的值很古怪,到底是怎么组织的呢???
带着问题我们进行求解:
首先是基础知识:
double数据类型的
实现使用的是
IEEE 754标准
如下规定:
````````符号位 阶码 尾数 长度
double 1 11 52 64
但是这到底是什么意思呢?
为了便于测试和说明,我把我的代码重新改正了一下:
即赋值一个double数据12.0(隐式类型转化,呵呵)
然后查看内存模型:
把28和40的二进制计算出来:
如下:
28:00101000
40:01000000
开始使用刚才的标准了。
double 1 11 52 64
(注意在开始钱要注意使用的CPU到底是大端的还是小端的,这个影响内存的存放顺序)(其实只是反正的问题)
我这的顺序是从大地址对应高位(大部分都是这种情况)
第一位是数据的符号位:0代表是正,1代表的是负。
在这里是0,所以是正数。
之后的11位代表的是指数(阶数)。注意指数是有正负的区别的,即从-1024 ~ 1023。因为指数可以为负,为了便于计算,规定都先加上1023(这个很重要!!!!)。但是为什么是加1023那就只能去问专家了,呵呵.
在这里是10000000010,因为这是加上1023之后的数据,需要变化回去,有一种简单的方法,那就是先将1去掉(存在1说明是正数),然后最后加上1,最后得到00000000011,即3,所以指数是3.
然后是尾数:
1000...(...号代表的是后面的0,在此处省略)
根据标准规定,尾数开始的那个1是省略的(这个也很重要!!),因此真正的尾数是1.100...
到现在你明白了吧,我们的结果出来了;
即:1.100...(二进制)然后小数点偏移3位(因为指数是3)即为1100,转化为十进制就是12.