C语言学习笔记——整数和浮点数在内存中的存储

我们都知道数据在内存中是以二进制的形式存储的,但是我们常用的数据有整型、浮点型、字符型,接下来我先介绍整型和浮点型在内存中的存储方式

一、整数的存储

整数的二进制表示方式有三种,分别是原码、反码、补码。

对于有符号整型,原码、反码、补码的第一位是符号位,0表示正,1表示负;而对于无符号整型就没有符号位。此外,在32位环境下的二进制表示方式,第一位是符号位,其余31位是数值位,对于不满31位的二进制数,高位补零;在64位下第一位同样是符号位,其余63位是数值位。对于

原码:将整数转换为二进制之后得到的二进制数字

反码:除了符号位不变,其余位置依次按位取反

补码:反码+1

需要注意的是对于正数和无符号整型而言,其原码、补码、反码相同

以69为例

十进制:69

二进制:01000101

原码:   00000000 00000000 00000000 01000101

反码: 00000000 00000000 00000000 01000101

补码: 00000000 00000000 00000000 01000101 

十进制:-69

二进制:- 01000101

原码:10000000 00000000 00000000 01000101

反码:11111111 11111111 11111111 10111010

补码:11111111 11111111 11111111 10111011 

 给大家看一行代码

int main(int argc, char *argv[]) {
	unsigned int i = -69;
	printf("%u",i);
	return 0;
}

而代码执行的结果是一个非常大的数

这就是因为-69在内存中存储的补码是11111111 11111111 11111111 10111011 ,而将它以无符号整型打印出来时将它的符号位视为数值位,因此打印时由于补码、反码、原码相同,结果就是一个非常大的数。

二、大小端的存储模式

对于超过一个字节的数据在存储时都有存储顺序问题,以一个十六进制的0x11223344的整型为例,整型有四个字节的空间,一个字节有8个比特位,也就是8个二进制位,换算过来就是两个十六进制位,那么0x11223344在内存中是11 22 33 44的方式存储还是以44 33 22 11 方式存储呢。从这就引申出来大小端的概念。

⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存 在内存的低地址处

⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存 在内存的⾼地址处

比如上面的0x11223344,小段存储就是 44 33 22 11,大端存储就是11 22 33 44


小端的优点就是内存的低地址存放数据低字节,大数强制转换小数时效率高,直接丢弃高地址数据即可;cpu在做数值运算时依次从低到高取数运算即可,效率高效。

大端优点:符号位在所表示数据内存的第一个字节,便于快速判断数据的正负和大小。

三、浮点数的存储

根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,对于任意的浮点数V,可以表示成下面的形式

V = (-1)^S*M*2^{E}

(-1)^{S}表示符号位,当S=0,V为正数;当S=1,V为负数

M表示有效数字,1\leqslant M< 2

2^{E}表示指数位

 以十进制的5.0为例,二进制就是 101.0 ,相当于 (-1)^0 * 1.01 * 2^2,对应的S=0,M=1.01,E=2

IEEE规定,对于32位的浮点数,最高位存储符号位S,接着8位存储指数E,剩下的23位存储有效数字M。

对于64位浮点数,最高位存储符号位S,接着11位存储指数位E,剩下的52位存储有效数字位M

 

 注意事项:

  1. 因为1<= M < 2,所以M可以写成 1.XXXXX 的形式。IEEE规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的 XXXXX 部分。

E是无符号整数,它的取值范围为 0~255 ;如果E为11位,它的取值范围为 0~2047 。但是,我 们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存⼊内存时E的真实值必须再加上 ⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

浮点数取得过程

E不全为0或不全为1

这时浮点数就采用下面的规则表示,即指数E的计算值减去127/1023,得到真实值,再将数字M前加1。

 ⽐如:0.5 的⼆进制形式为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的很⼩的数字。

0 00000000 00100000000000000000000

E全为1

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

0 11111111 00010000000000000000000

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值