C语言:浮点数的存储



浮点数在内存中的存储:

Float类型4个字节(这里看做8个字节来处理)

如:12.5(十进制)--------->如何转化二进制数?并且如何存储?

12.5=2^3+2^2+0+0.2^(-1)

即转化为1100.1。尽管转化为二进制的表示形式,但不可直接存储,要转化为科学计数的表示形式(如十进制12.5的科学计数表示为1.25*10^1)。(同理)所以1100.1的对应科学计数为1.1001*2^3

 

1个字节4位,这里存储8个字节有32位。

从左至右:第1位为数据的符号位(0表示正数,1表示负数)。第2~9位表示阶码(书上所说的其实就是进制上的指数)。第10~32位存尾数(即二进制科学计数表示下的小数1001部分)。

 

这里依旧以12.5为例:

1位:0(存12.5的正负,12.5是正数,存0

2~9位:1000 0010(这里有8位要用来存阶码,你可能会考虑到阶码也有正负,不知道如何存储它的符号。这里规定:按无符号数的方式来存储,(无符号8位可以存0~255),但阶码有正有负,所以将无符号的数以127作为分界,为负数时127减去该数,为正数时127加上该数,就可以简单地通过比较与127大小的关系得出阶码的正负。所以3表示为127+3=130,再转化二进制130------>1000 0010

10~32位:1001 0000 0000 0000 000(存尾数,但不够19位,依旧补0。补0规则一会会提到)

所以最终表示为:0100 0001 0100 1000 0000 0000 0000 0000(太多的01,不利于记忆,而且容易写错)

写成十六进制就方便的多了(二进制直接转化十六进制,每四位转化为一个十六进制),转化后:4 1 4 8 0 0 0 0

 

在电脑上调试测试之上面的结果后你会发现结果是:00 00 48 41。是不是和你想的有一点差距呢,数对了但顺序却错了,这是为什么呢?

这就和权重有关了,权重:位数越高,权重越大。如十六进制下的数:int a = 0x12 34 56 78;12的权重比78的权重高)。用四个格子(从左至右0~3即存储地址从低到高)去存这个数据就有两种方式:

第一种:低地址存放低数据(存储地址小的存放权重小的)。0号格子:78 1号格子:56,2号格子:34,3号格子:12;这种存放方式被称为小端。常见的是pc,inter。这就解释了为什么结果是00 00 48 41的原因了。

第二种:低地址存放高数据(存储地址小的存放权重大的)。0号格子:12 1号格子:34,2号格子:56,3号格子:78;这种存放方式被称为大端。常见的是手机,ARM。(是不是又想问,既然手机和inter不是一个大小端,那它们之间怎么可以聊天通信?因为在网络通信这一块只要是大小端不统一,就会默认把小端转成大端,实现通信。但小端和小端之间相互通信就不需要转,它们之间的通信就相当于本地通信,没必要转换。)

 

二进制位数不满,补0的原则:小数时右边补零;整数时左边补零。

其实就类似于十进制中,整数12300123没差别(指数字大小没区别),只是我们更喜欢看123;小数0.1230.12300数字大小也没区别。我们补零只是为了补满二进制位,并不会改变数字本身的大小。

你可能感兴趣的:(C语言:浮点数的存储)