为什么要用补码表示


用补码的主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。n位计算机,设n=8, 所能表示的最大数是11111111,若再加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的模为2(8)。 在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以了。把补数用到计算机对数的处理上,就是补码[1]。
最直观的得到一个负数的补码的方法是用28去减它,例如:
-1 的补码 100000000
-) 00000001
------------
= 11111111   (实际上就是1 + (11111111 – 1),先计算括号内,相当于按位取反,然后再加上外面的1。
 
首先说说无符号数的表示,一个字节可以表示28-1=256个数,00000000~11111111 分别表示0~255。这个很简单。
对于无符号数,一个字节同样只能表示256个数,那么怎么表示负数,一个比较好的办法就是将字节的最高位表示为符号位,其余7位表示数值,表示范围为-128~127, 00000000~01111111表示0~127, 10000001~11111111表示-1~-127吗,错!,实际上是10000000~11111111分别对应表示-128~-1,怎么会是这样呢,是不是搞错了,没错的,这就是补码,负数在计算中是以补码来表示的。
那么补码是怎么得到的呢?为了说明这个问题,让我们来先了解一下什么是原码和反码的概念。
原码:数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了,原码表示范围为-127 ~ -0, +0 ~ +127,除了最高位表示符号位,正负数在其余各位的表示是相同的,例如10000001表示 -1, 11111111表示-127。原码表示虽然很简单,但人们很快就发现用原码来进行加减运算会出问题:假设字长为8bits [2]
( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10
(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 显然不正确
因为两个整数的相加没有问题,所以问题出在带符号位的负数上,人们将负数除符号位的其它位逐位取反,就得到了反码。
 ( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10
(00000001) + (11111101) = (11111110) = ( -1 ) 正确
发现反码表示后,将加减数都表示成反码后,减法可以直接表示成加法,其结果似乎是正确的。但是:
( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10
 (00000001) + (11111110) = (11111111) = ( -0 ) 有问题.
问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的,于是就出现了补码,正数的补码不变,负数的补码是将其反码加1,这样表示后再看看上面的运算:
( 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 ) 正确
P.S.
一的补码(one's complement) 指的是正数=原码,负数=反码
而二的补码(two's complement) 指的就是通常所指的补码
在计算机系统中,数值一律用补码表示和存储。原因在于,使用补码可以将符号位和数值域统一处理,同时加法和减法也可以统一处理。此外,补码原码相互转换,其运算过程是相同的,不需要额外的硬件电路[^1]。 ### 补码的优势 1. **统一处理符号位和数值域**:补码将符号位和数值部分统一处理,简化了计算机的设计和实现。在补码表示中,正数和负数的符号位被自然地融入了数值的表示中,使得运算逻辑更加简单[^1]。 2. **统一加法和减法**:通过补码,加法和减法运算可以统一为加法操作。例如,计算 $ 3 + (-2) $ 可以直接通过补码相加实现,结果仍然正确。这种特性使得计算机只需要实现加法器,而不需要单独的减法器,从而降低了硬件复杂度[^3]。 3. **避免零的多重表示**:在原码和反码表示中,存在 $ +0 $ 和 $ -0 $ 两种不同的表示形式,这可能会导致计算错误。而补码解决了这个问题,确保零只有一种表示形式,进一步提高了计算的准确性[^4]。 4. **扩展数值范围**:补码表示能够多表示一个最低数。例如,在8位二进制中,原码或反码表示的范围为 $[-127, +127]$,而补码表示的范围为 $[-128, 127]$。这种扩展能力使得补码能够更有效地利用有限的二进制位数[^4]。 5. **溢出处理**:在补码运算中,溢出并不会影响结果的正确性。例如,在8位计算机上计算 $ 16 + (-8) $,通过补码加法可以得到正确的结果 $ 8 $。溢出的高位会被自动舍去,而不会影响最终结果[^5]。 ### 示例:补码加法 以下是一个简单的补码加法示例,计算 $ 3 + (-2) $: ```python # 3 的补码表示(8位) a = 0b00000011 # -2 的补码表示(8位) b = 0b11111110 # 补码加法 result = a + b # 输出结果(补码形式) print(f"结果的补码表示: {result:08b}") # 转换为十进制 print(f"结果的十进制值: {result}") ``` 运行结果: ``` 结果的补码表示: 00000001 结果的十进制值: 1 ``` 该示例验证了补码加法的正确性,通过简单的加法操作即可实现减法运算[^3]。 ### 总结 补码在计算机中的广泛应用得益于其统一的符号位处理、加法减法统一、零的唯一表示、扩展的数值范围以及对溢出的有效处理。这些优势使得补码成为计算机系统中最常用的数值表示方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值