【C语言】- 数据在内存中的存储

文章目录

介绍一下整数和浮点数在内存中的存储


一、整数在内存中的存储

整数的二进制有三种表示方法:

  • 原码:将数值按照正负数的形式翻译成⼆进制得到的就是原码
  • 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
  • 补码:反码+1就得到补码

有符号整数有两部分组成,符号位数值位, 而无符号整数只有数值位

  • 符号位;"0"表示正,"1"表示负
  • 数值位:除了最高位其余都是数值位

正整数的原码、反码、补码都一样,而负整数的三种各不相同

对于整形来说:数据存放内存中其实存放的是补码

为什么?

在计算机系统中,数值⼀律用补码来表示和存储。 原因在于,使用补码,可以将符号位和数值域统⼀处理; 同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是 相同的,不需要额外的硬件电路。

举个例子,在32位环境下,-6的原反补码:

而6的原反补都一样,为00000000 00000000 00000000 00000110

二、大小端字节序和字节序判断

1.大小端

超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题

按照不同的存储顺序,我们分为大端字节序存储小端字节序存储

  • 大端字节序存储:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
  • 小端字节序存储:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。

举个例子:

#include <stdio.h>
 int main()
 {
 int a = 0x11223344;
 return 0;
 }

 

 低字节:     就如个十、百、千、万一样,个位相对于其他就是低位

2.为什么有大小端?

一个地址单元对应一个字节,一个字节为8个bit位

可是在C语言中,有8bit的char型,也有16bit的short型,32bit的int型等等

另外,不止有8位的处理器,还有16位和32位的处理器

因此,当寄存器的宽度大于1个字节时,必然存在一个将多个字节安排的问题,也就存在了大小端的储存模式


三、浮点数在内存的存储

1.浮点数的存储

浮点数在计算机内部有个表示方法

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:

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

  • \left ( -1 \right )^{^{S}}: 表示符号位,当S=0.V为正数;  当S=1,V为负数
  • M      : 表示有效数字,M是大于等于1的,小于2的数
  • 2^{E}      : 表示指数位

举个例子:

十进制的6.0     ->    二进制 110.0    ==    1.1  *  2 ^ 2

要是看不懂可以看看这个:

十进制的1023   ==     1.023 * 10 ^ 3,     

在二进制中 10 就是  2,     

按照公式看来:

S是0    M是1.1   E是2 

负数也是这样的

十进制的-6.0     ->    二进制 -110.0    ==    -1.1  *  2 ^ 2

S是1    M是1.1   E是2 

IEEE 754规定:

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

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

 

 2.浮点数存的过程

IEEE 754对有效数字M和指数E,有一些特殊的规定

对于M来说:

因为 1<=M<2 ,所以M写成 1.xxxxxxx  

而计算机内部保存M时,会将第一位1给舍去,只保留后面的xxxxxx,之后读取时,再把1给填上

这样做的好处,可以节约一个有效数位,使其可以多存个有效数位

对于E来说

E是一个无符号整数

也就是说E为8个bit时,范围是0~255, E为11个bit时,范围是0~2047

但是科学计数法可以出现负数,所以IEEE 754规定,存入时,E的真实值要加上一个中间数

对于8位bit的E:中间数是127 ;    对于11位bit的E:中间数是1023 

例子:

  • 十进制 0.5  ->   二进制 0.1     ==   1.0 * 2^(-1)     E就是负数了
  • 2^10 E是10,那保存成32位浮点数时,保存成10+127=137,也就是10001001

 

3.浮点数取的过程

取出规则:指数E的计算值减去127(1023),得到真实值,再将有效数字M前加上第一位的1

这里根据指数E的情况分为三类:

E不全为0或不全为1

如:

0.5的二进制是0.1,    ->  1.0 * 2 ^ (-1)

S=0     

E=-1+127=126         ->   01111110   

M=1.0  去除第一位1,补齐0到23位  00000000000000000000000

即其二进制的表示形式是:   0    01111110     00000000000000000000000

E全为0

这里思考一下,这里的E已经加上了127(1023),但还是为0,这说明E的真实值是-127(-1023)

2^(-127)是一个非常非常小的数,所以 V的是无限接近于0

所以这里就规定,浮点数的指数E等于1-127 (1-1023)即为真实值

有效数字M不再加上第一位的1,而是还原为0.xxxxx的小数

从而表达正负0,已接近于0的很小的数字

0    00000000     00100000000000000000000

E全为1

同E全为0一样,这表达正负无穷大

0    00000000     00100000000000000000000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值