整数和浮点数在内存中的存储方式

为了方便表示和测试,以下用例都是在32位环境下进行的。

整数

在计算机里,正整数、负整数、0都是以补码形式存储的,由于数据类型导致的大小不同,如char型1个字节、int型4个字节等,计算机里会存在截断的现象: 

-1在32位环境下被存储为:00000000 0 0000000  00000001  00000000, 十进制为256,超出unsigned char的范围0~255,所以将被截断为00000000,十进制为0,a为0。

 由于存储时的截断机制,还会发生一些有趣的现象:

32位环境里

-128原码:10000000  00000000  00000000  10000000  

-128补码:11111111  11111111  11111111 10000000

-128减1等于-129,原码为:10000000  00000000  00000000  10000001

补码为:11111111 11111111 11111111 01111111

所以,若将-128减1再赋给char型的数据将会被截断为+127

因此,a永远不会小于-128,下面a的值将会不停在-128~127间循环

char a

for(int i=0; i<1000; i++){
        a=-i;// a=i也同样如此

}

 大小端存储

在计算机里,一个大于一个字节的数据在内存中通常是连续存放的,但存放顺序却有两种方式:

大端存储模式:指低位字节的内容存储在高地址,而高位字节的内容存储在低地址。

小端存储模式:指低位字节的内容存储在低位地址,而高位字节的内容存储在高地址。

 小端存储示例:(十六进制0x11223344中44是低位字节,11是高位,如同十进制1122,22是低位字节,11是高位字节)

数据在内存中的大小端存储方式与硬件架构相关,如英特尔和 AMD 的处理器就采用了小端存储。

浮点数的存储方式 

在计算机里,浮点数和整数的存储方式是不同的,在实际生活中,浮点数可以用科学计数法表示,如 (-1)x1.2e2 ,表示-0.012,所以国际标准IEEE中规定了任意一个二进制浮点数可以表示为:V = (-1) ^ S* M * 2^E,S控制正负,M表示有效数字,2^E表示指数部分(这里的2^E类似于十进制科学计数法的10^E)。例如:

100.11 ——> 1.0011*2^2      1001.11 ——>1.0012^3

二进制float型以32位存储其中最高1位为符号位(存储S),其后8位存储E(指数部分),接着23位存储M。二进制double型以64位存储其中最高1位为符号位(存储S),其后11位存储E(指数部分),接着52位存储M。

需要注意的是,S的值为1或0,M默认是1点几,所以M只需存储小数部分。E是指数,以无符号整数存储,但E在实际运用里可以为负整数,所以需要一个方法来存储负整数,这个方法就是中间数,float里中间数是127,double里中间数是1023,无论正负,存储E的数据使都需要加上这个中间数再存入内存,比如:存储二进制的float型1011.0——>1.0110*2^(-3),-3+127=124,所以

0        0111 1100          01100000000000000000000

S部分        E部分         M部分

若内存里E数据为127,则实际值为0。

浮点数的取出:1.E不为全0或全1。此时取出的顺序即为存入顺序的倒序

 2.E全为0。此时E的值默认为1-127=-126(1-1023=-1022),M为0.xxxx,此时该浮点数为一个接近于0的极小数。

3.E全为1。如果M不全为0,表示一个极大的数字,如果M全为0,表示无穷大。

本文知识点已经全部讲解完毕,接下来是2道示例用于理解上面的知识点:

int a = 5;
float* b = (float*)&a;
printf("%f ", *b);      

打印的内容不是预期的5.000000而是0.000000,原因是整数和浮点数的存储方式不同。

正整数a在计算机里以补码 00000000 00000000 00000000 00000101存储,将这串二级制赋给floatb,会将其视为浮点型来解读:

0 0000000 000000000000000000000101

S为0,E全为0,E=1-127=-126,此刻一个接近于0的浮点数赋给了b,b为0。

同样的:

float a = 0.125f;//1.0 -3 0 00111 1100 00000000000000000000000
int* b = (int*)&a;
printf("%d ", *b);

打印结果为1040187392而不是浮点型转化为整型被截断为0。

0 00111 1100 00000000000000000000000 表示0.125

0011 1110 0000 0000 0000 0000 0000 0000 这是b实际存储的补码,数值是1040187392。

我们也可以将其转化为16进制,观察它的存储模式:

0 0111110 0000 0000 0000 0000 0000 0000        二进制

00111110 00000000 00000000 00000000       二进制

     3E           00               00            00        16进制

 在内存里a以小端模式存储:

完。 

  • 22
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值