目录
1.引言
想必大家经过一段时间的学习,对于整数在内存中的存储已经有所了解(不了解我们接下来也会讲解),实际上整数在内存中是以补码的形式保存的,那么浮点数呢?聪明的你或许看到这里还是一脸懵逼的状态,但是不要惊慌,接下来我会先对原码、反码、补码这一块知识进行补充,然后在对浮点数的存储进行详细的解析。
2.基础知识
关于原码反码与补码
计算机中的整数有三种表示方法,即原码、反码和补码。 三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位负整数的三种表示方法各不相同。
原码
直接将二进制按照正负数的形式翻译成二进制就可以。
反码
将原码的符号位不变,其他位依次按位取反就可以得到了。
补码
反码+1就得到补码。
此外还有一点需要注意
正数的原、反、补码都相同。
下面为了帮助大家理解我会举几个例子
比如10在内存中是如何存储的呢?(以32为操作系统为例)
根据我们上面所讲的知识我们可以很快写出10的原码反码与补码?
00000000000000000000000000001010//10的原码,首位0为符号位代表正数
01111111111111111111111111110101//反码,符号位不变,其他位取反
01111111111111111111111111110110//补码,即反码+1
如果看到这你觉得没问题那么恭喜你上当了,众所周知正数的原反补码都是相同的(逃)
那接下来我们看看-10呢?同样我们可以很快的写出它的原码反码与补码
10000000000000000000000000001010//注意符号位为-1代表负数
11111111111111111111111111110101//符号位不变,其他位取反得到反码
11111111111111111111111111110110//反码+1得到补码
而如果我们想要将补码转化回原码我们只需要再做一次同样的操作即可
即符号位不变,其他位取反,然后+1
那么我们现在已经有了足够的基础知识,下面我们将开始讲解浮点数在内存中是如何存储的。.
3.浮点数在内存中的存储
根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面的形式:
1. (-1)^S * M * 2^E。
2. (-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
3. M表示有效数字,大于等于1,小于2。
4. 2^E表示指数位。
举个例子:
十进制的5.5,写成二进制是 101.1 ,相当于 1.011×2^2(二进制的科学计数法) 。 那么,按照上面的格式,可以得出s=0,M=1.011,E=2。
IEEE 754规定:
对于32位的浮点数,最高的 比特就业课 1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。如下图。
而对于64位的浮点数则是如下图所示。
IEEE 754对有效数字M和指数E,还有一些特别规定。
前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。 IEEE754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后等于可以保 存24位有效数字。
而对于指数E我们分为以下三种情况 :
E不全为0或不全为1:
浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将 有效数字M前加上第一位的1。 比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为 1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23 位00000000000000000000000,则其二进制表示形式为: 0 01111110 00000000000000000000000
E全为0 时:
浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于 0的很小的数字(因为此时E非常小)。
E全为1 时:
如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。
那么本篇的内容到这里就结束了,由于笔者能力有限难免会有所纰漏请大家在评论区积极指正。