我们想想浮点数float类型的数据在计算机中是怎样存储的?为了了解这个问题,首先必须知道计算机数据是二进制存储的。其次必须了解float类型数据的存储方式。
float类型数据就是不是整数的实数。比如12.25、0.25、0.5、5.0等。我们将以上几个数转换为二进制就是以下形式:
12.25-------------1100.01 (2^3+2^2+0+0+0+2^(-2))
0.25---------------0.01 (0+0+2^(-2))
0.5-----------------0.1 (2^(-1))
5.0----------------1001.0 (2^2+0+0+2^(0))
二进制小数点前各位的权值是2^(n-1).小数点后每位的权值是2^(-n)。这样我们就可以将十进制书转化为二进制数。但是浮点数在计算机中到底怎样存储的。我们写一段代码做一个试验。
#include
int main( )
{
unsigned char *pchar;
float x=12.5;
pchar=&x;
printf("*(pchar+0)=0x%x\n",*pchar);
printf("*(pchar+1)=0x%x\n",*(pchar+1));
printf("*(pchar+2)=0x%x\n",*(pchar+2));
printf("*(pchar+3)=0x%x\n",*(pchar+3));
}
*(pchar+0)=0x0
*(pchar+1)=0x0
*(pchar+2)=0x48
*(pchar+3)=0x41
我们声明了一个float 类型x,将初值初始化为12.5.使用一个unsigned char指针指向它第一个字节地址。并且输出以下四个字节。我们将这四个字节拼起来:
0x00,0x00,0x48,0x41。二进制显示:0000 0000 0000 0000 0100 1000 0100 0001。因为计算机存储时高地址存储高位。为了方便我们将其倒过来:
0100 0001 ,0100 1000,0000 0000, 0000 0000
我们是不是比较奇怪,为什么没有12.5的值。我们就必须查询 IEEE 754-2008 了解float存储方法。他的结构是这样的。
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
31 30 23 22 0
S符号位,因为float数有正有负。
30~23, 是8位指数位。
22~0, 23位尾数部分。尾数是二进制小数点。
我们将0100 0001 ,0100 1000,0000 0000, 0000 0000存储到以上结构中重新划分一下。
0, 1000,0010,1001 000, 0000 0000 0000 0000 。
0,符号位
1000,0010,130指数
1001 000, 0000 0000 0000 0000 尾数。
我们需要继续学习 IEEE 754-2008 。符号位是0,表示该数为正数。
1000,0010,130 指数其实就是3+127.IEEE规定指数必须加127后存储。即127+指数。
所以如果指数存储结果大于127(111,1111)指数为正。所以如果指数存储结果小于127(111,1111)指数为负。存储结果减去127即可得到指数。按照以上的例子130-127=3,也就是指数为3.
IEEE规定尾数都是二进制小数,必须在最高位(22位之前)补1,结果才是真正的尾数。
1001 000, 0000 0000 0000 0000真正的值位1100,1 000, 0000 0000 0000 0000,
现在我们应该明白了0, 1000,0010,1001 000, 0000 0000 0000 0000 其实就是
1.10010000000 0000 0000 0000*2^3 .也就是1100.1即12.5.
同样方法我们可以写出0.25的存储方式0011 1110 1000 0000 0000 0000 0000 0000
0,符号位
011 1110 1 ,125 ,125-127=-2
000 0000 0000 0000 0000 0000,尾数最高位补1,1000 0000 0000 0000 0000 0000
0011 1110 1000 0000 0000 0000 0000 0000其实就是1*2(-2).即0.25.
大家可以使用今天提供的代码使用VC输出0.5与5.0存储形式。在根据IEEE规则倒退一下,看看是否正确。
文章评论(0条评论)
登录后参与讨论