计算机的数据存储

一.  数据类型的介绍

0424c18e31264a2eb40c932991d7240b.png

本文主要介绍基本类型数据在计算机中的存储方式。char类型的存储和表示本质上还是使用ASCII码值,故放在整型介绍。

二.  整型的存储方式

1.  原码,反码和补码

数据在计算机中是以二进制序列的形式存在,又因为计算的需要产生了原码,反码和补码。

对于正数,它的原码,反码和补码相同。

对于负数,原码:符号位(最高位)为1,其余依次按二进制转换

                  反码:符号位不变,其余按位取反

                  补码:反码+1

内存中存储的都是补码。如下:

19c0e82d4e4b4d51b22cfb79a43cb871.jpeg

2.  大小端的存储方式

在上图中可以观察到,-10补码的十六进制序列与在内存中的存储顺序好像是“相反”的,这就涉及到了大小端字节序存储。

大端字节序存储:把一个数据的低位字节放到高地址,高位字节数据放到低地址。

小端字节序存储:把一个数据的低位字节放到低地址,高位字节数据放到高地址。

比如ABCDEFAC这个数据,AB属于高位字节,内存中0x11223344这个地址,11属于低地址。

两种存储方式与编译器的种类有关,可以通过相关的算法程序来判断编译器对数据的存储方式。

3.  整型提升

char类型的打印应该采用%c,但是如果使用了%d,就要涉及到整型提升。

比如

char a = -1;

signed char b = -1;

unsigned char c = -1;

printf("a = %d , b  = %d, c = %d" , a , b , c);

在这个程序中,a,b,c会打印出不同的数值。

5f8a81f60499423198c3041a024d729c.png     

b是-1,符合逻辑,这里解释一下a和c为什么是这样的数值。

一个字节是由八个比特位,即八个二进制位组成的。所以,

对于a,

整型a的原码反码和补码是这样的:(按照原码,反码,补码的顺序)

10000000000000000000000000000001

11111111111111111111111111111110

11111111111111111111111111111111

char类型定义a后要进行整型截断,丢失高三个字节的内容,留下11111111

打印时又要进行整型提升,有符号位补符号位,没有补0

于是,a的补码反码和原码序列为

11111111111111111111111111111111

11111111111111111111111111111110

10000000000000000000000000000001

恰好为-1。

对于c,

不同点发生在整型提升,由于c被unsigned修饰,所以没有符号位,需要补零

所以c的补码变为

00000000000000000000000011111111

由于unsigned修饰,原码反码补码相同,所以输出255

4.  char类型的取值范围

可以如下依次列出://第一列是补码

00000000     0

00000001     1                                                 

00000010     3

00000011      4

...............

0 1111111       127

10000000       -128

10000001       10000000    11111111   -127

...............

1111111 0         11111101     10000010   -2

11111111           11111110     10000001    -1

即-128~127

对于-128的表示,涉及到正零和负零,在二进制编码中,原码和反码是区分正零和负零的,补码不区分。原码中,正零和负零只有符号位不同,在反码中,全零表示正零,全一表示负零。

对于unsigned char类型,由于没有符号,它的表示范围是0~255,即2^8-1

三.  浮点数的存储方式

按照IEEE754的标准,二进制32位(单精度)浮点数和64位(双精度)浮点数的表示如下:

f = (-1)^S * (M) *2^e 其中:e=E-127或1023

其中,

(-1)^S表示符号位,当S=0时,f为正数;当S=1时,f为负数。

M为有效数字,根据科学计数法,其首位必须为1,所以这里舍去1,内存中可以直接存储小数部分,提高精度,大于0,小于1。

2^e表示指数位。

E作为一个阶数,内存中使用的是unsigned int,但使用时可能会出现负数情况,这是就要加上一个中间数,对于32位,这个数是127,对于64位,这个数是1023

输出浮点数时,若E不全为零或不全为1时,用E的计算值减去127,M前添上1.

                         若E全为零,E=1-127=-126,M前加上0.

                         若E全为1,数字很大,处理方式同第一条。

以5.5为例:

二进制为  f = 101.1 = 1.011*2^2 = (-1)^0*(1.011)*2^2

S = 0, E = 2, M = 1.011

32位下    S占1bit,E占8bit,M占23bit

64位下    S占1bit,E占11bit,M占52bit

float a = 5.5;

0  10000001  01100000000000000000000

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值