目录
引言:
我们都知道学习C语言离不开对内存的理解和操作。
那么对于整数和浮点数,在我们内存中到底是怎么进行存储的呢?
为什么有的浮点数无法进行精确的数据存储呢?
今天由我来为大家演示整数和浮点数的存储方式。
整数在内存中的存储方式:
话不多说,我们先来了解一下整数在内存中的存储方式,首先我们知道,一个整数(int),占4个字节,那么一个字节又有8个bit位,所以我们就可以知道,一个整数会占用4*8也就是32个bit位。而每一个比特位能存储二进制的’0’/‘1’。
我为大家画一个图供大家直观的观看:
可以看到我们画出了32个bit位,用来表示我们的int,那么有的同学就要问了,这二进制序列怎么看啊?其实很简单,在我们学习内存存储的时候,需要学习一个必不可少的知识,也就是权重。
什么是权重?
通过这个图我们可以看到,我们二进制的每一位都有自己的权重,从低位到高位分别是,2^0、2^1、2^2、2^3、2^4、2^5........。
最后我们将这些权重值加在一起,因为int以十进制存储,所以算出来后就是它本身的值。
例如上方,因为它之前位数全是0,所以我们先看后八位,0000 1011.从低位向高位算,也就是2^0 + 2^1 + 2^3 = 1+2+8 =11,所以存在int中的数是11.
可以看到确实是如此,所以相对于权重,希望我们已经有了一个初步的认识。
原码反码补码:
对于二进制我相信我们已经并不怎么陌生了。那么对于整数的二进制表示形式有三种,即原码反码补码,也称为原反补。
对于原反补有这样的规则:
正数的原码反码补码相同。
这里解释一下是什么意思呢?我们先了解一下原码:原码是对于有符号/无符号int中的内容转换成2进制的形式。最高位为符号位(无符号没有符号位,全部都是有效数值位),最高位为符号位,这里为大家画图演示一下:
当符号位为0,也就是正数的时候,他的原码反码补码都相同。
负数的原码反码补码:
当一个数是负数的时候,他的符号位为1,后31位为有效数值位。
负数-11的原码如上所示。那么对于负数的反码有如下规定:
负数的反码:负数的反码是按照,符号位不变,其他有效位按位取反,具体如下:
如上所示,负数的-11反码遵循符号位不变,其他位按位取反即可得到反码
负数的补码:负数的补码遵循反码+1,即可得到补码。具体如下所示:
可以看到,上述即是负数-11的补码,按照反码+1即可得到补码。而在计算机中存放的就是补码。
那么反码怎么转换成原码呢,其实也很简单,按照取反+1即可得到原码。具体如下所示:
按位取反。
取反后+1.即可得到原码。
以上即是整型在内存中存放的方式,对于无符号来说,所有位都是有效数值位,没有符号位。
浮点数在内存中的存储方式:
在我们常见的浮点数中,如:3.141592,5.12,等,我们知道,浮点数有:float,double,long double。
那么根据国际标准IEEE754中,任意一个二进制浮点数V可以表示成如下形式:
V=(-1)^S * M * 2^E
其中,(-1)^S表示符号位,当S等于0时,V为正数,当S等于1时,V为负数。
M表示有效数字,M大于1,小于2.
2^E表示指数位。
举个例子来说明,例如十进制的11.0,它写成二进制是:1011.0,相当于1.011 X 2^3
按照上面V的格式,可以写出,S为0,M为1.011,E为3.
那么十进制的-11,它的二进制码是:-1011.0,相当于-1.011 X 2^3,那么可知,S为1(因为是负数),M为 1.011,E为3.
那么对于32位的浮点数,最高的1位存放的是S,接着8位存放指数E,剩下23位存放M
对于64位浮点数,最高的1位存放的是S,接着的11位存放的是指数E,剩下的52位存放有效数字M。
如上是在32位下存储方式。
如上是在64位下的存储方式。
IEEE754对于有效数字M和指数E还有如下特别规定:
前面提到,M可以写成1.XXXXXX的形式,其中XXXXXX表示小数部分,那么在IEE754中规定,在计算机内部保存M的时候,默认这个数字的第一位总是1,因此可以舍去这个1,只保存后面的小数部分XXXXXX,例如保存1.101的时候只保存101,到需要使用进行读取的时候,再将1加上去,这样的目的是为了节省一个字节的空间给有效数值位,并且可以保存更大的数字,以32位为例,留给M的空间只有23位,如果我们将1舍去,等于就可以保存24位有效数字,可以保存的数字就会越大。
指数E:
首先对于E而言,它是一个无符号整数(unsigned int)
对于E而言,它在32位下,E可存空间有8位,它的取值范围就在0~255之间,如果E为11位,它的取值范围就在0~2047,但是我们知道,E是有负数的情况的,所以在IEEE754规定,存入内存的时候,E的真实值必须加上一个中间值,对于8位而言,中间值位127,对于11位的E而言,中间值为1023,比如,2^3,E的值为3,保存成32位浮点数的时候,就需要用:3+127=130.即
1000 0010
浮点数在内存中E的取出方式:
对于指数E而言,取出的时候还分为三种情况:
E不全为0或不全为1
这个时候,浮点数采用指数E的值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1.
E全为0
这时,浮点数的E等于1-127(或1-1023)就为真实值,有效数字M不再加上第一位的1,而是还原为0.XXXXXXX的小数,这样做可以表示+-0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示+-无穷大(其中,正负号取决于符号位S)
以上即是整型和浮点型在内存中的存储和取出方式,感谢大家观看,喜欢的话可以点赞收藏+关注哦,谢谢大家。