计算机中的加减法(原码、反码、补码)

本文介绍了在计算机中如何使用补码进行减法运算,通过4位二进制数的例子解释了正数和负数的表示,并展示了如何将减法转换为加法,涉及原码、反码和补码的概念。通过补码,我们可以让计算机仅进行加法操作来实现减法,解决了超出存储范围的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设我们的计算机比较低级,只能计算4个bit(位)的数。

原码

4个bit可以存下多大的数?

只存正数

如果我们只存正数,可以表示的范围是0000-1111,也就是0 至 15,一共可以存16个数。

既存正数,也存负数

如果我们继续要存正数,也需要存负数,就需要用一个bit来表示符号位。

假设约定用最高位表示符号位,1表示负数,0表示正数。

则范围变成了 1111-0111,也就是 -7至 7,一共可以存15个数。

为啥只能存15个数了呢,因为此时 1000 与 0000都表示0,重复了。

加法

我们做一个在取值范围内的加法运算,似乎很轻松,结果也没有问题。

减法

 a  - b   =  a + (- b)

其实两个正数的减法也可以转化为 正负数相加。

做一个简单的正负数相加运算: -2  +  1

 结果居然是-5,很明显不正确。

转换思路

对于计算机来说“负数”这个概念太复杂了,我们换个角度来思考这个问题。

文章的开头有一个限制,我们的计算机只能存储4个bit的数,如果超过4个bit,则会忽略高位。

现在是夜里11点,我的闹钟了指向了11,两个小时候时针会指向13吗?自然不会,两个小时后指针指向1。

那么在时钟的世界里,就可以用   (11 + 2)来表示  (11 -  10)。

这就是一个从减法转化为纯粹正数相加的过程。发现规律没? 2 + 10  =  12 刚好是时钟的“容量”

知道这个方法后,我们再来计算 -2 + 1,怎么把他转化为两个正数相加呢。

(!注意,这个时候我们别去考虑什么符号位,我们的目的是彻底转化为两个正数相加)

4个bit如果都用来存正数,可以存16个,容量就是16。

16 - 2 = 14

14的二进制是 1110

 结果是1111,也就是15,我们期望的结果应该是 - 1,即使把最高位看作是符号位,结果也不对,肯定还需要一个转化的过程。

假设我们的这种方法是对的,我们还需要解决两个问题。

1、-2(1010)是怎么转化到  1110的。

2、我们获得结果1111怎么转化为最种结果1001(-1)。

这就需要引入反码和补码的概念了。

反码

我们人类看的懂的是原码,计算机看得懂是补码,反码就显得格外没有地位。

确实,反码只是原码转化为补码的一个中间产物,只是用来过度的。

正数的反码 =  正数的原码

负数的反码 =  负数的原码 除符号位外,全部取反

补码

正数的补码 = 原码

负数的补码 =  反码  +  1

-2 的原码1010,取反加1后,得到1110,解决了第一个问题。

我们之前运算得到的值是1111,尝试对这个数取补码,得到  1001。

1001不正是我们需要的结果 -1 吗?解决了第二个问题。

总结

计算机是很“单纯”的,只会做正数的加法,他不懂什么是负数,什么是减法。

但我们可以利用它的特点——如果计算结果超过了存储的范围,则丢弃溢出的数。引入补码的概念,彻底将减法转化为加法。

之前写的 &0Xff,也是类似的思想,有兴趣可以看看:

https://blog.csdn.net/qq_37855749/article/details/115736609

### 真值、原码反码补码的概念 在计算机科学中,为了表示带符号的二进制并简化硬件设计中的法器电路结构,引入了不同的编码方式来处理正负数。这些编码方法包括真值、原码反码补码。 #### 1. 真值 真值是指实际存在的值,在十进制下可以直接理解为人们日常使用的整形式。当涉及到二进制表达时,则需要通过特定的方式将其转换成机器能够识别的形式[^1]。 #### 2. 原码 对于任意给定的一个有符号定点小或整X(假设字长n),如果它是非负数,则其最高位设为0;如果是负数,则最高位置1,并且剩下的部分按照绝对值得到相应的二进制序列作为该原码表示[^4]。 #### 3. 反码 - 对于正值而言,它的反码与其原码完全一致; - 而对于负值来说,除了保持原有的符号位外,其他各位均需按位求反得到最终结果[^2]。 #### 4. 补码 这是最常用的一种编码方案,它不仅解决了减法操作复杂度高的问题,还使得两个同号不会溢出造成错误。具体定义如下: - 正数补码等于自身的原码; - 负数补码则是先计算出对应的反码再对其最低有效位上1所获得的新串列。 ### 加减法规则 由于采用补码可以统一法与减法的操作过程——即无论是做还是做减都可以转化为简单的模意义下的运算,因此现代计算机内部几乎都使用补码来进行四则运算: ```python def add(a, b): # a 和 b 是两个 n 位二进制字符串代表的补码 result = bin(int('0b' + str(a), base=2) + int('0b' + str(b), base=2))[2:] while len(result)<len(a): result='0'+result return result[-len(a):] def subtract(a, b): # 实现a-b的效果 neg_b = ''.join(['1' if c=='0' else '0' for c in b]) # 得到b的反码 temp_result = add(neg_b,'1') # 将上述所得转为补码 final_result=add(a,temp_result) return final_result ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值