int_float_double数据类型的存储格式。
一段用来检测编辑器存储方式的程序
1 //date : 2013/8/16 2 //designer :pengxiaoen 3 //function check the C programmable language system 4 5 #include "stdio.h" 6 #include "string.h" 7 8 typedef unsigned char *byte_pointer; 9 10 void show_bytes(byte_pointer start, int len) 11 { 12 int i ; 13 for(i=0;i<len;i++) 14 printf("%.2x",start[i]); 15 printf("\n"); 16 17 system("pause"); 18 } 19 20 void show_int (int x) 21 { 22 show_bytes((byte_pointer)&x, sizeof (int)); 23 } 24 25 26 void show_float (float x) 27 { 28 show_bytes((byte_pointer)&x, sizeof (float)); 29 } 30 31 void show_double (double x) 32 { 33 show_bytes((byte_pointer)&x, sizeof (double)); 34 } 35 36 37 //void show_pointer (void *x) 38 //{ 39 // show_bytes((byte_pointer)&x, sizeof(void *)); 40 //} 41 42 43 44 int main () 45 { 46 int i=12345; 47 int ival; 48 float fval; 49 double dval; 50 // int *ip; 51 52 ival = i; 53 // ip = &i; 54 fval = (float)ival; 55 dval = (double)ival; 56 57 show_int (ival); 58 show_float (fval); 59 show_double(dval); 60 // show_point (ip); 61 }
中间的指针一段不知道为什么我的dev 显示连接错误。所以就先屏蔽掉了。在目前讨论的话题之外,先搁置。
显示的结果
分析: i=12345;转换成十六机制就是 0x3039 说明我这个是个小端机;
好,现在将数据读出来 (00 00 30 39 )16 = (0000 0000 0000 0000 0011 0000 0011 1001)2
(46 40 E4 00 )16 = (0100 0110 0100 0000 1110 0100 0000 0000)2
(40 C8 1C 80)16 = (0100 0000 1100 1000 0001 1100 1000 0000 ...................)2
int float double 存储格式 这本《深入理解计算机系统》第二版 第三十页,突然中止讨论了,下面如果还有再补上。
补充 1: 先看46 40 E4 00
红色部分前面加上一个1就成了12345.
第一个bit为0 表示 数据为正
第一个红色bit 与第一个bit之间的 8个bit 为 100 0110 0 = 140
再看 (00 00 30 39 )16 = (0000 0000 0000 0000 0011 0000 0011 1001)2部分
转化成科学计数法 1.1 0000 0011 1001 * 2^13.
因为二进制科学计数法小数点前面一位恒为1,所以就省略存储。只需要存储
1 0000 0011 1001 00 0000 0000。 精确到小数点后的十八位 (2^-18)
存储幂数 13 的位置在第一个bit 也就是符号位,和有效位之间的那8个bit
实际存储时 在原有的幂数基础上加了127 也就是 111 1111 。
最后看 (40 C8 1C 80)16 = (0100 0000 1100 1000 0001 1100 1000 0000)2 部分
第一个bit也就是第63个bit 是0 表示是正数
第 62bit 至52bit 100 0000 1100 = 1036 幂数13= 1036-1023
后面的存储格式和float 的相同,只是精度加大了。
而 13 + 127 = 140 所以这8 个bit存储的是140 。至于为什么要加上127。double中为什么要加上一个1023. 这个还么有找到答案。如有幸看到相关资料或者是网友指点迷津,再补充
补充二:
先看下面一个小段的程序
1 //date : 2013/8/16 2 //designer :pengxiaoen 3 //function : check the momery ,how did it to save the number of float 4 5 #include "stdio.h" 6 #include "string.h" 7 8 9 typedef unsigned char *byte_pointer; 10 11 int main() 12 { 13 int m; 14 int i ; 15 float f= 1.0; 16 byte_pointer bp; 17 printf("the number is %f\n",f); 18 19 bp = (byte_pointer)&f; 20 i = sizeof (f); 21 for(m=0;m<i;m++) 22 printf("%.2x",bp[m]); 23 printf("\n"); 24 25 system("pause"); 26 }
执行结果
如果将第15行进行修改 赋值为-1
好,现在可以分析了
(1)d = (3f 80 00 00 )h = (0011 1111 1000 0000 0000 0000 0000 0000)b
(-1)d = (bf 80 00 00)h = (1011 1111 1000 0000 0000 0000 0000 0000)b
第一个是符号位,上面已经介绍了,不作赘述。011 1111 1 = 127 代表 幂数为0 ,有效位为0
float 类型在存储幂数的时候加上了127 就可以让幂数范围控制在了 -127 ~ 128 之间
double类型类似的将幂数范围控制在 -1023 ~ 1024 之间
综上所述 float 类型存储占用32bit 依次是符号位 第31bit 表示方式 0 表正数 1表示负数
幂 第30bit ~ 23bit 共8bit 表示方式 (100 0000 + 幂数 -1)
小数部分 第22bit ~ 0bit 共23bit 表示方式(小数部分)整数部分为1,默认,不单独存储。
double类型存储占用64bit 依次是符号位 第63bit 表示方式 0 表正数, 1 表示负数
幂 第62bit ~ 52bit 共11bit 表示方式 (1000 0000 000 + 幂数 -1)
小数部分 第51bit ~ 0 bit 共52bit 表示方式(小数部分) 整数部分为1 ,默认,不单独存储。