原码 补码 反码

原码 补码 反码


2024年5月4日发(作者:)

大家都知道数据在计算机中都是按字节来储存了,1个字节等于8位(1Byte=8bit),而计算机只能识别

0和1这两个数,所以根据排列,1个字节能代表256种不同的信息,即2

8

(0和1两种可能,8位排列),

比如定义一个字节大小的无符号整数(unsigned char),那么它能表示的是0~255(0~2

8

-1) 这些数,

一共是256个数,因为,前面说了,一个字节只能表示256种不同的信息。别停下,还是一个字节的无

符号整数,我们来进一步剖析它,0是这些数中 最小的一个,我们先假设它在计算机内部就用8位二进

制表示为00000000(从理论上来说也可以表示成其他不同的二进制码,只要这256个数每个数对应 的二

进制码都不相同就可以了),再假设1表示为00000001,2表示为00000010,3表示为00000011,依次

类推,那么最大的那个数 255在8位二进制中就表示为最大的数11111111,然后,我们把这些二进制码

换算成十进制看看,会发现刚好和我们假设的数是相同的,而事实上,在计 算机中,无符号的整数就是

按这个原理来储存的,所以告诉你一个无符号的整数的二进制码,你就可以知道这个数是多少,而且知

道在计算机中,这个数本身就是以 这个二进制码来储存的。比如我给你一个2个字节大小的二进制码,

首先声明它表示的是无符号的整数:00000000 00000010,我们把前面的0省略,换算一下,它表示的也

是数值2,和前面不同的是,它占了2个字节的内存。不同的类型占的内存空间不同,如在我的电 脑中

char是1个字节,int是4个字节,long是8个字节(你的可能不同,这取决于不同的计算机设置),

它们的不同之处仅仅是内存大的能表示的不同 的信息多些,也就是能表示的数范围更大些(unsigned int

8*4

能表示的范围是0~2-1),至于怎么算,其实都是一样的,直接把二进制与十进制相互转换,二进制就

是它在计算机中的样子,十进制就是我们所表示的数。啊哈,原来这些都是可以计算的呀,我曾经还以

为不同的计算机储存的原理是不同的,取决于商家的喜好呢,呵呵。说 了这么多怎么还没有提到原码、

反码和补码呀,别急别急,心急吃不了热豆腐,呵呵,因为无符号的整数根本就没有原码、反码和补码。

(啊,那不是被欺骗了, 5555````我告诉妈妈去,哥哥欺负我)都说了别急嘛,你就不想想我说了这么

半天的无符号整数,那么有符号的整数怎么办啊?

呵 呵,对,只有有符号的整数才有原码、反码和补码的!其他的类型一概没有。虽然我们也可以用二进

制中最小的数去对应最小的负数,最大的也相对应,但是那样不 科学,下面来说说科学的方法。还是说

一个字节的整数,不过这次是有符号的啦,1个字节它不管怎么样还是只能表示256个数,因为有符号所

以我们就把它表示 成范围:-128-127。它在计算机中是怎么储存的呢?可以这样理解,用最高位表示符

号位,如果是0表示正数,如果是1表示负数,剩下的7位用来储存数 的绝对值的话,能表示2

7

个数的

绝对值,再考虑正负两种情况,2

7

*2还是256个数。首先定义0在计算机 中储存为00000000,对于正数

我们依然可以像无符号数那样换算,从00000001到01111111依次表示1到127。那么这些数对应的二进

制 码就是这些数的原码。到这里很多人就会想,那负数是不是从10000001到11111111依次表示-1到

-127,那你发现没有,如果这样的话那么一 共就只有255个数了,因为10000000的情况没有考虑在内。

实际上,10000000在计算机中表示最小的负整数,就是这里的-128,而且实际上 并不是从10000001到

11111111依次表示-1到-127,而是刚好相反的,从10000001到11111111依次表示-127到-1。负 整数

在计算机中是以补码形式储存的,补码是怎么样表示的呢,这里还要引入另一个概念——反码,所谓反

码就是把负数的原码(负数的原码和和它的绝对值所对应 的原码在数职位上相同)各个数值位按位取反,

是1就换成0,是0就换成1,如-1的原码是10000001,和1的原码在数值位上相同,那么 -1的反码就

是11111110,而补码就是在反码的基础上加1,即-1的补码是11111110+1=11111111,因此我们可以算

出-1在计算机 中是按11111111储存的。总结一下,计算机储存有符号的整数时,是用其补码进行储存

的,0的原码、补码都是0,正数的原码、补码可以特殊理解为相同,负数的补码是它的反码加1。下面

再多举几个例子,来帮助大家理解!

十进制 → 二进制 (怎么算?要是不知道看计算机基础的书去)

47 → 101111

有符号的整数 原码 反码 补码

47 00101111 00101111 00101111(正数不区分原码、反码和补码)

-47 10101111 11010000 11010001(负数补码是在反码上加1)

再举个例子,学C语言的同学应该做过这道题:

把-1以无符号的类型输出,得什么结果?(程序如下)

#include

void main()

{

short int n=-1;

cout<<(unsigned short int)n<

}

首先在我的电脑中short int类型的储存空间是2个字节,你的可能不同,我说过,这取决于你的计算

机配置。它能储存2

8*2

=65536个不同的数据信息,如果是无符号那么它的范围是0~65535(0~2

16

-1),

如果是有符号,那么它的范围是-32768~32767(-2

15

~2

15

-1)。 这道题目中,开始n是一个有符号的短整

型变量,我们给它赋值为-1,根据我们前面所说的,它在计算机中是以补码11111111 11111111储存的,

注意前面说了是2个字节。如果把它强制为无符号的短整型输出的话,那么我们就把刚才的二进制把看

成无符号的整型在计算机中储存的 形式,对待无符号的整型就没有什么原码、反码和补码的概念了,直

接把11111111 11111111转化成十进制就是65535,其实我们一看都是一就知道它是范围中最大的一个数

了。呵呵,就这么简单。你个把上面的源代码编译运行看看, 如果你的电脑short int也是两个字节,

那就会和我得一样的结果。你可以先用这个语句看看:cout<

里的短整型占多少的储存空间,也可以用sizeof来看其它任何类型所分配的储存空间。

最后提醒一句,关于数据如何在计算机中储存的,这里只适用于整型的数据,对于浮点型的是另一种方

式,这里我们暂时就不深究了。

补码的计算和引进补码的原因:

数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).

这就是机器数的原码了.假设机器能处理的位数为8.即字长为1byte,

原码能表示数值的范围为(-127~-0 +0~127)共256个.

有了数值的表示方法就可以对数进行算术运算.

但是很快就发现用带符号位的原码进行乘除运算时结果正确,

而在加减运算的时候就出现了问题,如下: 假设字长为8bits

( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10

(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 显然不正确.

因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上,

对除符号位外的其余各位逐位取反就产生了反码.反码的取值空间和原码相同且一一对应.

下面是反码的减法运算:

( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10

(00000001) 反+ (11111110)反 = (11111111)反 = ( -0 ) 有问题.

( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10

(00000001) 反+ (11111101)反 = (11111110)反 = ( -1 ) 正确

问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.

于是就引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.

在补码中用(-128)代替了(-0),所以补码的表示范围为:(-128~0~127)共256个.已知某数的补码,

先求某数的反码,然后在对反码+1,就得到某数的原码.比如:

已知某个数的补码是:10100110

先对10100110求反,得:11011001

再对11011001加1,得: 11011010

那么这个数为-86

原码表示的范围为:-(2^(n-1)-1)~+(2^(n-1)-1),

反码表示的范围为与原码一样.

补码表示的范围为:-2^(n-1)~+(2^(n-1)-1),

其中n为机器字长。

注意:

0的补码是唯一的,为0000,0000 [+0]补=[-0]补=0000,0000 -0的反码为1111,1111

8bit表示数值时(-128)没有相对应的原码和反码, (-128) = (10000000)

补码的加减运算如下:

( 1 ) 10- ( 1 ) 10= ( 1 )10 + ( -1 )10 = ( 0 )10

(00000001)补 + (11111111)补 = (00000000)补 = ( 0 ) 正确

( 1 ) 10- ( 2) 10= ( 1 )10 + ( -2 )10 = ( -1 )10

(00000001) 补+ (11111110) 补= (11111111)补 = ( -1 ) 正确

所以补码的设计目的是:

⑴使符号位能与有效值部分一起参加运算,从而简化计算机的运算规则.

⑵使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计

所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。

看了上面这些大家应该对原码、反码、补码的知识印象更深了吧!!

个人总结:

负数的原码与其对应正数的原码除符号位(最高位)相反外(负数的符号位为1,正数的符号位为0),

其余数值位是相同的

可以这样认为,正数只有原码,其原码就是其二进制表示,正数在计算机中即是以其原码形式存储的,

负数有原码和补码,负数在计算机中是以其补码形式存储的

补码=原码的反码+1

原码表示的范围为:-(2^(n-1)-1)~+(2^(n-1)-1),

反码表示的范围为与原码一样.

补码表示的范围为:-2^(n-1)~+(2^(n-1)-1),

其中n为机器字长。

注意:

0的补码是唯一的,为0000,0000 [+0]补=[-0]补=0000,0000 -0的反码为1111,1111

8bit表示数值时(-128)没有相对应的原码和反码, (-128) = (1000 0000)

对应的-2的8n-1次方都没有对应的原码和反码

16bit表示数值时(-32768)没有相对应的原码和反码, (-32768) = (1000 0000 0000 0000)

对应的-2的16n-1次方都没有对应的原码和反码


发布者:admin,转转请注明出处:http://www.yc00.com/web/1714752339a2508738.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信