C语言整数和浮点数在内存中存储的形式

        我们都知道一个整数类型的数据在c语言中是4个字节的大小,也就是32个比特位,而一个单精度浮点型的数据也是4个字节大小,双精度浮点型数据是8个字节大小,那究竟整数和浮点数,在内存中是怎么存放的呢,到底有什么区别?为什么我们有的时候输入一个浮点数,再从内存中拿出来的时候,这个浮点数却和我们输入的数字有了一定的误差呢?

        我们都知道数据在内存中都是以二进制的形式进行存储的,一个整形是4个字节,也是就是说我们在内存中用32个0 1来表示一个整数,而这32个二进制的0 1的第一位被称为是符号位,0表示证书,1表示负数,为了计算机计算时的便捷,我们在计算机中存储的都是数据的二进制补码。那原码、反码、补码又是什么呢?原码就是把这个整数直接转化成二进制的形式,而正整数的原码、反码、补码是完全一致的,也就是说在计算机中存储的正整数的补码就是它的原码;而负整数就有所区别了,负数的反码是将原码除符号位以外的所有数字取反,即原码位0则变为1,原码为1则变为0;而补码就是在反码的基础上+1即可。;例如一个1是一个正整数,它的原码是00000000 00000000 00000000 00000001,最高位是符号位,因为正整数的原码、反码、补码一致,所以它在内存中存储的就是00000000 00000000 00000000 00000001;-1是一个负整数,它的原码就是10000000 00000000 00000000 00000001,最高位的符号位是1,表示这是一个负数,要知道它在计算机中存储的形式就要把原码转化为补码,先求它的补码,符号位不变,其他所有位置取反,就变成了11111111 11111111 11111111 11111110,再把反码+1,就得到了11111111 11111111 11111111 11111111,这个就是它的补码,所以-1在内存中存储的形式就是11111111 11111111 11111111 11111111。

        在了解浮点数的存储之前,我们先了解一下科学计数法,我们也可以把一个浮点数写成类似科学记数法法的形式,比如1.5,我们就可以把1.5转化为(-1)^0 * 0.15 *10^1,但是对于计算机而言,浮点数存储的也是它的二进制形式,二进制中同样的小数点后面的每个数都有他们相应的位权大小

所以我们就可以把1.5转化为1.1,把它科学记数法用表示就是(-1)^0 * 1.1* 2^0;根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

V   =  (−1)^S M ∗ 2^E,因此把1.5转化为标准形式后就变成了(-1)^0 * 1.1* 2^0,所以对应的S就是0,M就是11,E就是0,对于一个32位的浮点数来说,最高1位用来存储符号位S 接下来的8位用来存储指数E,剩下23位用来存储数值位M
对于一个64位的浮点数来说,最高1位用来存储符号位S 接下来的11位用来存储指数E,剩下52位用来存储数值位M
        在存储有效数字M和指数E时也有一些特殊的规定,通过我们改写的形式可以看出,M是一个<=1并且>2的一个数字,也就是说M永远可以写成1.xxxxxxx,其中xxxxxxx就是小数部分,因此,在计算机保存时,默认这个数的第一位总是1,因此可以被舍去,只保存xxxxxxx部分,比如在保存1.1时,只会保存1,等到读取的时候再把第一位给添上,这样就也节省了一位有效数字,因此对于32位浮点数量来说虽然只有23个数值位,但是可以保存的有效位数是24位。
    而E是一个无符号整形,如果它是8位,它的取值范围就是0~255;如果它是11位,它的取值范围就是0~2047,但是在科学记数法中,E是可以出现负数的情况的,因此规定 存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^3的E是3,所以保存成32位浮点数是,必须保存成3+127=130,即10000010。
        而指数E从内存中取出时,又分为三种情况:
        1.E不全为0或不全为1
        这个时候的E就是存入E时的逆过程,即数值E的值减去127(或1023),得到真实值,再把有效数字M前加上第一位1
        比如0.75的二进制为是0.11,由于规定有效数字的第一位必须为1,所以将小数点右移1位,所以变为1.1 * 2^(-1),它的M真实值就是-1,把它存入内存时要+127就变为-1+127(中间值) =126,表示为01111110,有效数字1.1去掉整数部分变为1补齐0到23位10000000000000000000000,所以0.75的内存中的存储形式就是
0 01111110 10000000000000000000000

但是因为二进制的小数部分只能用2^(-n)来表示,所以并不是所有的小数都能够用二进制来表示,计算机在存储时,只能计算到一定的有效位数,取得一个近似的数,所以有时候我们输入一个浮点数,输出时却发生了一定的误差就是因为这个数不能用二进制精确保存,在有效位数的计算取得近似数时,发生了一定的误差,导致输入和输出的值发生一定的改变。

        2.E全为0

        这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还 原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。

        3.E全为1

        这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s)。

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值