float类型的数据在内存中是如上存储的,float类型的存储方式如下(摘自博客 http://blog.csdn.net/yezhubenyue/article/details/7436624):
取原文中的部分总结如下:
浮点型变量在计算机内存中占用4字节(Byte),即32-bit。遵循IEEE-754格式标准。
一个浮点数由2部分组成:底数M和指数E。
底数部分 使用2进制数来表示此浮点数的实际值。
指数部分 占用8-bit的二进制数,可表示数值范围为0-255。但是指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float的指数可从 -126到128. 底数部
分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。 到目前为止,底数部分23位加上指数部分8位使用了31位。那么前面说过,float是占用
4个字节即32-bit,那么还有一位是干嘛用的呢? 还有一位,其实就是4字节中的最高位,用来指示浮点数的正负,当最高位是1时,为负数,最高位是0时,为正数。
举例将17.625换算成 float型。
1、将17.625换算成二进制位:10001.101 ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即 1/8 如果不会将小数部分转换成二进制,请参考其他书籍。
2、再将 10001.101 向右移,直到小数点前只剩一位 成了 1.0001101 x 2的4次方(因为右移了4位)。
此时我们的底数M和指数E就出来了:底数部分M,因为小数点前必为1,所以IEEE规定只记录小数点后的就好,所以此处底数为 0001101 。
指数部分E,实际为4,但须加上127,故为131,即二进制数 10000011 符号部分S,由于是正数,所以S为0.
综上所述,17.625的 float 存储格式就是:01000001100011010000000000000000 //这就是我们下文中程序运行的结果
1 #include<stdio.h> 2 3 void printBin(int n) //取整数,求整数部分的二进制数 4 { 5 if(n==0) 6 return; 7 printBin(n/2); 8 printf("%d",n%2); 9 } 10 11 void printFin(float f)//求小数部分的二进制数 12 { 13 int i=0; 14 float a; 15 a=f-(int)f; 16 if(a==0) 17 { 18 printf("0"); 19 return; 20 } 21 while(a!=1) 22 { 23 i++; 24 a=a-(int)a; 25 a=a*2; 26 printf("%d",(int)a); 27 if(i>28)//为什么有这个设置呢?因为float最大存储28位二进制小数值,实际上由于有进位,所以小数点后的数值长度会小于28 28 return; 29 } 30 return; 31 } 32 33 void Binary(float f) 34 { 35 float a; 36 a=f; 37 printBin((int)a); 38 printf("."); //两个二进制数之间用.进行连接 39 printFin(a); 40 putchar(' '); 41 return; 42 } 43 44 45 int main(void) 46 { 47 int i; 48 union 49 { 50 float f; 51 int b; 52 }none; 53 54 float a; 55 int len=sizeof(int)*8; 56 printf("Please input F:"); 57 scanf("%f",&none.f); 58 Binary(none.f); 59 printf("%d ",none.b); 60 for(i=0;i<len;i++) 61 { 62 printf("%4d",i); 63 } 64 putchar(' '); 65 66 for(i=0;i<len;i++) 67 { 68 printf("%4c",('0'+((unsigned)(none.b&(1<<(none.b-1)))>>len-1)));//这个程序是移位将数据的存储二进制形式打印出来 69 none.b<<=1; 70 } 71 putchar(' '); 72 73 return 0; 74 }
程序运行结果如下:
1 Please input F:17.625 2 10001.101 //17.625的二进制形式 3 1099759616 //17.625的内存中的二进制存储形式所对应的整形值 4 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //内存中的位数 5 0 1 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0