为什么计算机要使用反码/补码

本文探讨了计算机为什么要使用反码和补码。反码用于在没有减法器的数字电路中通过加法实现减法操作,正数反码不变,负数除符号位外取反。补码的引入解决了0在计算机中非唯一编码的问题,通过将负数反码加1,确保每个数字有唯一编码,并保持减法变加法的计算能力。

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

一、为什么需要反码?

反码的作用就相当于数学中的负数。

对于小学生来说,会做的算术题是:5-3,但是不会做3-5。于是,我们上初中的时候,数学里就引进了一个新的概念:负数。引入负数之后,本来是减法的运算就可以变成加法来实现:

3-5=3+[-5]=[-2],中括号代表“负数”,“负数”就是我们人为给出的数学术语。

对于计算机来说,会做的算术题是:5+3,但是不会做3-5。于是,我们就在编码里引进了一个新的概念:反码。引入反码之后,本来是减法的运算就可以变成加法来实现:

3-5=3+[-5]=[-2],中括号代表“反码”,“反码”就是我们人为给出的计算机术语。

这里,你一定有一个疑问:为什么计算机只会做5+3,不会做3-5。这是因为在计算机的数字电路中只有加法器,没有所谓的“减法器”。不是说计算机厂商不会设计减法器,因为聪明的人既然发明了方法能够用加法来实现减法操作,那为什么还需要画蛇添足的弄一个减法器?

接着说:那么反码要怎么定义才能实现减法变加法的功能呢?聪明的人想的办法如下:

1.正数反码保持原码不变:3=[0_0000011]

2.负数除最高位(正负符号位)外,全部取反(0变1,1变0):-5=1_0000101取反=[1_1111010]

于是3+[-5]=[-2]的计算过程为:

[0_0000011]+[1_1111010]=[1_11111101]

这样,这种反码方法就成功实现了目标!至于为什么,我想只有数学家能给出解释了。

二、为什么需要补码?

都是因为“0”这个特殊数字的存在。

先问你一个问题:0是正数还是负数?你肯定会说:0既不是正数也不是负数,这是我们初中学到的数学知识。这个回答没有问题,所以以后每次碰到0,人们都不会把它当正数或负数。

那么计算机呢?计算机不同于人脑,计算机在碰到任何数字之前只根据最高位的符号位来判断正负性,“0”表示正数,“1”表示负数。

前面我们推论了为何要用反码,那么用8位二进制反码表示的正数范围: +0 —— +127;负数范围: -127 —— -0。但是,其中有两个特殊的编码会出现:

[0_0000000]=+0 (反码)

[1_1111111]=-0 (反码)

其实,+0和-0代表的都是0。这样一来,“0”这个数字在计算机中的编码就不是唯一的了。对于计算机来说,这是绝对不行的,因为任何数字都只能有1个编码。

于是,聪明的人就做了这样一个决定:把0当成正数,也即+0,这样0的编码就变成:0_0000000。那8位二进制表示的正数范围仍然是: +0 —— +127。

但是,对于负数就必须要做调整,也即-0必须要让位---1_1111111这个编码不能表示-0。我们可以把负数整体向后“挪动1位”:只要将8位二进制表示的负数范围从:-127 —— -0变成:-128 —— -1,就能成功解决问题。

那么怎么整体挪动1位呢?方法就是反码+1。{1_1111111}编码就不再表示-0,而变成了-1。顺着推,最小的编码{1_0000000}就是-128。

我们给这个反码+1又人为的取了一个新的名字,叫补码。于是乎,补码的定义如下:

1.正数补码保持原码不变:3={0_0000011}

2.负数先求反码,然后再加1:-5=[1_1111010]+1={1_1111011}

于是3+{-5}={-2}的计算过程为:

{0_0000011}+{1_1111011}={11111110}

至此,通过补码就成功解决了数字0在计算机中非唯一编码的问题,且也能实现减法变加法。

所以,在计算机的世界里,0是正数。这点和我们学的数学不一样。

{0_1111111}=+127 (补码)

{0_0000000}=+0 (补码)

{1_1111111}=-1 (补码)

{1_0000000}=-128 (补码)

转载https://zhuanlan.zhihu.com/p/105917577

### 原码、反码补码的计算器在线工具 对于原码、反码以及补码的学习和计算需求,可以借助一些在线工具来快速完成转换。这些工具能够帮助理解数值在计算机中的表示方式及其相互关系。 #### 在线工具推荐 目前网络上有多种可用的原码、反码补码转换工具,以下是几个常见的选项: 1. **Calculator.net 的进制转换功能** 此网站提供了基础的二进制与其他进制之间的转换支持,虽然未专门标注为“原码/反码/补码”,但可以通过手动输入数据并验证其结果[^2]。 2. **Binary Tools** Binary Tools 是一款专注于二进制和其他编码形式之间转换的实用程序。它不仅提供简单的二进制到十进制转换,还允许用户指定是否需要显示原码、反码补码的结果[^3]。 3. **GeeksforGeeks 提供的相关资源** GeeksforGeeks 上有详细的教程说明如何实现手动生成原码、反码补码的过程,并附带了一些交互式的 JavaScript 小脚本用于演示目的[^1]。 4. **Code Beautify 组合型转换器** Code Beautify 中有一个综合性的数字系统转换页面,其中包含了从任意一种编码转至另一种的功能模块,非常适合初学者用来练习巩固知识点[^2]。 #### 使用方法指导 当访问以上提到任一平台时,请按照如下提示操作: - 输入待处理整数(可选正负号) - 选择目标输出格式——即希望得到的是哪种表现形式的数据结构 - 查看即时反馈区域内的最终答案 下面给出一段 Python 实现简易版本此类算法的例子以便于进一步探讨原理层面的内容: ```python def get_original_code(num, bit_length=8): """获取给定数字num对应的原码""" if num >= 0: original_code = bin(num)[2:].zfill(bit_length) else: original_code = '1' + bin(abs(num))[2:].zfill(bit_length - 1) return original_code def get_complement_one(original_code): """基于传入的原码original_code返回相应的一次补码(反码)""" complement_one = ''.join(['1' if c == '0' else '0' for c in original_code]) return complement_one def get_complement_two(complement_one): """依据一次补码complement_one得出二次补码也就是真正的补码表达式""" n = len(complement_one) carry = 1 complement_two_list = [] for i in range(n-1,-1,-1): current_digit_sum = int(complement_one[i]) + carry if current_digit_sum==2: complement_two_list.append('0') carry = 1 elif current_digit_sum==1: complement_two_list.append('1') carry = 0 else:#current_digit_sum must be zero here since we add only one to the number. complement_two_list.append('0') carry = 0 complement_two=''.join(reversed(complement_two_list)) return complement_two.zfill(len(complement_one)) if __name__ == "__main__": test_num=-9 ori=get_original_code(test_num) comp_one=get_complement_one(ori) comp_two=get_complement_two(comp_one) print(f"Original code of {test_num} is :{ori}") print(f"One's Complement (Reverse Code):{comp_one}") print(f"Two's Complement (Final Result):{comp_two}") ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值