> 文档中心 > 整形数据的存储,补码的三种计算方式,这些你都懂吗?

整形数据的存储,补码的三种计算方式,这些你都懂吗?

目录

首先要明白整形家族的分类,和基础知识。(32位下)

原反补的计算

数据在内存中的存储

一些实例


首先要明白整形家族的分类,和基础知识。(32位下)

类型 char         int short long
字节个数 1   4 2 4
取值范围 -128~127 -2^30~2^30-1 -2^14~2^14-1 -2^30~2^30-1
类型 unsigned char unsigned int unsigned short unsigned long
字节 1 4 2 4
取值 0~255 0~2^31-1 0~2^15-1

0~2^31-1

原反补的计算

计算机中的整数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位 负整数的三种表示方法各不相同。

原码 :就是把数据按照正负数形式翻译为2进制即可。

反码 :就是原码的符号位不变,其他的按照比特位按位取反即可。

补码 :就是原码+1得到补码,符号位也要参与计算 。

正数的原码,反码,补码一样。

那么由补码怎么得出原码呢?

方法1

把原码反码的过程逆序下。这个是最常见的,就不在举例子了。

方法2

int  b =  -15;

原 :10000000 00000000 00000000 00001111

反: 11111111 11111111 11111111 111110000

补 :11111111 11111111 11111111 11110001

补码在按位取反:10000000 00000000 00000000 00001110

补码在按位取反:10000000 00000000 00000000 00001111

方法3

 int c = -14;

原 :10000000 00000000 00000000 00001110

反 :11111111 11111111 11111111 11110001

补:11111111 11111111 11111111 11110010

右向左找出第一个1,然后把从右向左到符号位之间的全都按位取反

补:11111111 11111111 11111111 11110010

取反:10000000 00000000 00000000 00001110

(红色字体是按规则取反)

数据在内存中的存储

对于整形数据而言,在内存中是以补码形式存储的。

那么怎么放入呢?

比如  int a = 1;

补码为 :00000000000000000000000000000001

16进制显示为00 00 00 01,是怎么放进去呢?

一般常见的有两种 。

00 00 00 01    或者  01 00 00 00 

其中01的部分称为数据的低权值位。

权值:就像是10进制中的个位的1就没十位上的1表示的大一样,根本原因是权值的原因

数据的低权值位放在低地址处是小端存储

数据的低权值位放在高地址处是大端存储

 这个图是小端存储。

为什么要有补码?

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

简单来说:就是为了方便减法,不用借位。

一些实例

例 1:

int a = 1;

int b = -1;

相加为0,这很简单,那么用补码的形式来运算下。

a 原/反/补:00000000 00000000 00000000 00000001

b原:10000000 00000000 00000000 00000001

b反:11111111 11111111 11111111 11111110

b补:11111111 11111111 11111111 11111111

a补+b补 为

1 00000000 00000000 00000000 0000000 一共33位比特位,但是int只有32位比特位呀。

所以就发生截断,那么会截断那个比特位呢?是截断那个1呢?还是截断最后一个0呢?

这样来看,截断的是最高的比特位,留下的是最低的32位比特位

例 2:

unsigned int a = -1;printf("%u\n",a);printf("%d\n",a);

这样可以数据存进去吗?

答案是可以的,因为数据存储时不会考虑类型,你只是把数据的补码存入开辟好的空间中就可以了,至于类型什么时候用呢?其实是在读取数据时才起作用,输出时,因为是有符号数输出,所以内存中存的数据11111111 11111111 11111111 11111111以有符号打印。是-1,以无符号打印是2^31-1.

例3:

    char a = -128;printf("%u\n", a);

这样打印结果是什么呢?

首先a的补码是1000000 因为%u是unsigned int,a是char,所以a要进行整形提升%u是无符号,所以补位补最高位,变成11111111 11111111 11111111 10000000,打印为4294967168。

例 4:

    char a = 127;printf("%d", a);

这样打印结果呢?

首先a是char,原反补一样是 01111111,%d是int,所以对a进行整形提升,补位时补符号位0

变成00000000 00000000 00000000 01111111打印是127

今天的补充内容是为了明天的移位符进行铺垫,今天就到这里。

明天见~~~

松山湖人才网