我们总是说八位二进制表示的数的范围是:-128——127,

可是我们知道在八位二进制原码【(-127~-0 +0~127)共256个】,反码【(-127~-0 +0~127)共256个】,都没有表示到-128,而为什么说八位二进制数的表示范围就是-128——127呢,其实在于补码!补码的表示范围是【(-128~0~127)共256个】,所几进制所表示的范围是尤其补码来确定的。比如说,十进制-128在八位二进制原码中表示不了,八位二进制反码中表示不了,而八位二进制补码中可以表示,那么就可是说十进制-128是可以表示的,可以用八位二进制来表示的,所以其范围就有了-128,终期八位二进制范围就是:-128——127.

八位二进制数为什么表示的范围是: -128 —— +127?

 

计算机对有符号数(包括浮点数)的表示有三种方法:原码、反码和补码

8位原码能够表示数的范围是 -127~127

8位反码能够表示数的范围是 -127~127

8位补码能够表示数的范围是 -128~127

既然范围是-128~127,那肯定是用补码表示的。

 

 

 

下面摘抄网上的一些讲解,觉得蛮不错的。

原码:最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。

1、原码、反码和补码的表示方法

(1)原码:在数值前直接加一符号位的表示法。

例如:符号位  数值位

[+7]原= 0000 0111B

[-7]原=1000 0111B

留意:a. 数0的原码有两种形式:

[+0]原=00000000B  [-0]原=10000000B

b. 8位二进制原码的表示范围:-127~+127

(2)反码:

正数:正数的反码与原码相同。

负数:负数的反码,符号位为“1”,数值部分按位取反。

例如:符号位 数值位

[+7]反= 0000 0111B

[-7]反=1111 1000B

留意:a. 数0的反码也有两种形式,即

[+0]反=00000000B

[- 0]反=11111111B

b. 8位二进制反码的表示范围:-127~+127

 

(3)补码

2)补码的表示:

正数:正数的补码和原码相同。

负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。

例如:符号位 数值位

[+7]补=0000 0111B

[-7]补=1111 1001B

补码在微型机中是一种重要的编码形式,请留意:

a.采用补码后,可以方便地将减法运算转化成加法运算,运算过程得到简化。正数的补码即是它所表示的数的真值,而负数的补码的数值部份却不是它所表示的数的真值。采用补码进行运算,所得结果仍为补码。

b.与原码、反码不同,数值0的补码只有一个,即[0]补=00000000B。

c.若字长为8位,则补码所表示的范围为-128~+127;进行补码运算时,应留意所得结果不应超过补码所能表示数的范围。

2.原码、反码和补码之间的转换

由于正数的原码、补码、反码表示方法均相同,不需转换。

在此,仅以负数情况分析。

(1已知原码,求补码。

例:已知某数X的原码为10110100B,试求X的补码和反码。

解:由[X]原=10110100B知,X为负数。求其反码时,符号位不变,数值部分按位求反;求其补码时,再在其反码的末位加1。

1011 0100原码

1100 1011 反码,符号位不变,数值位取反

1+1

1100 1100 补码

故:[X]补=11001100B,[X]反=11001011B。

 

(2)已知补码,求原码。

分析:按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 有方法。

例:已知某数X的补码11101110B,试求其原码。

解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。

1110  1110补码

1001 0001 符号位不变,数值位取反

1+1

1001  0010 原码

1.3.2有符号数运算时的溢出题目

请大家来做两个题目:

1)(+72)+(+98)=?

0 1 0 0 1 0 0 0 B    +72

+ 0 1 1 0 0 0 1 0 B  +98

1 0 1 0 1 0 1 0 B     -42

2)(-83)+(-80) = ?

1 0 1 0 1 1 0 1 B    -83

+1 0 1 1 0 0 0 0 B   -80

0 1 0 1 1 1 0 1 B    +93

思考:这两个题目,按照正常的法则来运算,但结果显然不正确,这是怎么回事呢?

答案:这是由于发生了溢出。

 

 

     几点注意的地方:

              <1>计算机里无论什么进制数都是以补码表示的!

 

<2>原码中:+0(00000000B) -0(10000000B)

反码中:+0(00000000B) -0(11111111B)

补码中:(00000000B) -128(10000000B)

<3> 如何通过原码、反码、补码当前数字来得出原数字的大小:

              正数:直接计算出当前数字,就是原数字

原码:

              负数:直接计算出当前数字,就是原数字

 

              正数:直接计算出当前数字,就是原数字

反码:

             负数:当前数字+所求原数字=-127

 

              正数:直接计算出当前数字,就是原数字

补码:

              负数:当前数字+所求原数字=-128

<4>用补码表示的数,参加加法、减法(当然都转为为加法运算)乘法、除法运算时,即在做加法运算时,满二进一位,但请注意,采用补码进行运算,所得结果仍为补码。

<5>已知补码,求原码。

分析:按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1的方法。

例:已知某数X的补码11101110B,试求其原码。

解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。

1  1  1  0  1  1  1  0   补码

1  0  0  1  0  0  0  1   符号位不变,数值位取反

                     1   +1

1  0  0  1  0  0  1  0   原码

 

 

参考资料:

网址:

http://blog.csdn.net/csw_100/article/details/5844751

     数值在计算机中表示形式为机器数,计算机只能识别0和1,使用的是二进制,而在日常生活中人们使用的是十进制,”正如亚里士多德早就指出的那样,今天十进制的广泛采用,只不过我们绝大多数人生来具有10个手指头这个解剖学事实的结果.尽管在历史上手指计数(5,10进制)的实践要比二或三进制计数出现的晚.”(摘自<<数学发展史>>有空大家可以看看哦~,很有意思的).为了能方便的与二进制转换,就使用了十六进制(2

4)和八进制(23).下面进入正题.

 

数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了.假设机器能处理的位数为8.即字长为1Byte,原码能表示数值的范围为

(-127~-0 +0~127)共256个.

    有了数值的表示方法就可以对数进行算术运算.但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题:

( 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)反 = ( -127) 反= ( -0) 还有问题?!

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

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

问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大).

于是又引入了补码(用最高位表示符号位,如果是0表示正数,如果是1表示负数,剩下的7位用来储存数的绝对值的话,能表示128个数的绝对值,再考虑正负两种情况,128*2还是256个数。首先定义0在计算机中储存为00000000,对于正数我们依然可以像无符号数那样换算,从00000001到01111111依次表示1到127。那么这些数对应的二进制码就是这些数的原码(和原码一样)。到这里很多人就会想,那负数是不是从10000001到11111111依次表示-1到-127,那你发现没有,如果这样的话那么一共就只有255个数了,因为10000000的情况没有考虑在内。所以-1到-127不能那样表示(和原码的表示方法相同了,当然错了)。实际上,10000000在计算机中表示最小的负整数,即-128(原指-0的)。因为 -128+1=-127,那么把10000000加上1即10000001表示-127就容易计算很多了。这样,从10000001到11111111就刚好依次表示-127到-1。这就是所谓的补码。). 那么补码是怎样直接地转换得来呢?负数的补码就是对反码加一;而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:

(-128~0~127)共256个.

注意:当字长为8位时,(-128)没有相对应的原码和反码, (-128) = (10000000) (为什么?还有为什么8位整数表示的范围是-128~127,而不是-127~128呢?想过没有,为什么二进制10000000在原码和反码中表示0,在补码中它不表示0,保证了0表示的唯一性,但是它为什么表示负数,而不是正数,你也许会说,因为它符号位是1呀,表示负数呀,对,继续,+128我们用补码怎么表示,包括符号位,表示为010000000,超过了2个字节,如果截取低8位,那么是10000000,最高位(符号位)是1,表示的是一个负数了!我们再看看-128的机器码是多少,原码110000000,反码101111111,补码110000000,截取低8位即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等其他高级语言中使用的都是原码。看了上面这些大家应该对原码、反码、补码有了新的认识了吧!int 被设计为计算机处理效率最高的整数类型。很显然,溢出只能出现在两个同符号数相加或两个异符号数相减的情况下。

 

版权声明:本文为Tears123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Tears123/archive/2013/03/16/tears.html1