深入理解计算机中的补码、反码、原码
问题:
- 我们每天用的钟表,其实只有1~12这12个数字,但我们日常会说13点、17点之类的。
问:13点在钟表上哪个位置?
答:很简单嘛,1点的位置。
你不觉得奇怪吗,为啥13点会和1点在同一个位置?换言之,13和1有啥关系,17和5有啥关系? - 计算机里为啥要用加法替代减法?
- 当然是加法电路设计比减法电路设计简单了,加法电路详见CPU之图解算数逻辑单元ALU
- 怎么用加法替代减法?
一、基本概念
1.0、余数(remainder)
在算术中,当两个整数相除的结果不能以整数商表示时,余数便是其“余留下的量”。当余数为零时,被称为整除。
即:被除数 / 除数 = 商……余数,用数学表示:
a = qd + r, 0 <= r < d,其中a为被除数,q为商(quotient),d为除数(divisor),r为余数(remainder)。
举例:当除数为4时,任何正数除以4时,余数总在0, 1, 2, 3中;
0 / 4 = 0 …… 0
1 / 4 = 0 …… 1
2 / 4 = 0 …… 2
3 / 4 = 1 …… 3
4 / 4 = 1 …… 0
5 / 4 = 1 …… 1
6 / 4 = 1 …… 2
7 / 4 = 1 …… 3
8 / 4 = 2 …… 0
……
如上,被除数从0开始递增时,余数会在0, 1, 2, 3中一直循环下去,这就是同余

现在我们考虑除数为10时,则余数在0~9这10个数字中出现;把这10个数字同样置于圆盘中,如上图所示。
在0-9这10个数字的圆盘中,再也不会有其它数字了,也就是我们限定了我们的数字范围为0~9,数字个数(记为模)为10。
给定圆盘上任一个数字作为起始点(记为 src),任一个数字为 终止点(记为dest),我们考虑从src出发,如何到达dest,可以 前进(记为 + ),可以后退(记为 - )。
举例:
src = 3,dest = 4;
- 前进1步(+1),即 3 + 1 = 4;
- 后退9步(-9), 即 3 - 9 = 4;
src = 3,dest = 3;
- 前进0步(+0),即 3 + 0 = 3;
- 后退(9+1)步(-(9+1)), 即 3 - ( 9 + 1) = 4;// 因为我们限定了数字范围为0~9,所以写成(9 + 1)
src = 5,dest = 9;
- 前进4步(+4),即 5 + 4 = 9;
- 后退6步(-6), 即 5 - 6 = 9;
通过上面的例子,发现了吗?
- 对于确定的起止点(如src = 3,dest = 4),不管前进或者后退,我们都可以到达,也就是说前进(1步)等价于后退(9步),
- 前进步数和后退步数之和为模(10),模意味着啥?
- 模意味着走了一圈,一个轮回,起点走一圈,又回到了起点
1.1、补数(complement)
定义:对于给定的进位制,相加后能使自然数 a 的位数增加 1 的最小的数。
说人话:就是前面前进和后退的步数等价的组合(如1和9、2和8、3和7、4和6),也即可以组成模(如10)的组合。
即:
当 a = 1时,a只有1位数字(即个位)要想将a变成2(1+1)位数字10(十位、个位),需要增加9。
所以 9是1的补数;当然1也是9的补数,即1、9互为补数;
同理:2、8互为补数;
3、7互为补数;
4、6互为补数;
问: 36的补数是多少?
答:64
根据上面定义,我们知道对于整数a,a的补数 = 模 - a(a>=0);
补数有啥用?
还是回到之前我们0~9这10个数字的圆盘上来,我们来算小学生都会的10以内的加减法:


一顿操作猛如虎,一看结果:直呼OMG,

正如上图所示:减掉一个数,等价于加上这个数的补数。
这里有个重要的前提:数字是有范围的(上面我们限定了0~9这10个数字)
1.2、减法
根据我们上面的结论:当数字是有范围的,则对于这个范围内的数字,减掉一个数,等价于加上这个数的补数,我们可以用加法替代减法,进一步:减去一个正数相当于加上这个正数对应的负数。
还是回到我们前面提到的圆盘上来,我们把这条结论实践下:
- 我们先在坐标轴上标出0~9这10个数字范围,然后移动这个范围框,使框内正负数个数大致相等,如下图所示,数字范围变成了
-5 ~ 4这10个数字。

- 将坐标轴上的数字范围同步映射到圆盘上。

- 此时,圆盘上数字的运算可以用圆盘外相对应的数字进行替代,即圆盘上的数字范围已经改变了,由之前的0 ~ 9 变成了现在的 -5 ~ 4 。

1.3、补码
看到这里,不知道你是否认可前面的推导结论?
不认可?不认可就对了。聪明的你一定发现了上面的计算的问题:
1 - 5 = -4,在我们映射后变成了 1 + 5 = 6 但 -4 不等于 6?虽然圆盘上6确实对应**-4**,但我们需要的是正确的结果-4,怎么将6转换成-4?

- 好了,为了后面好叙述,我们先给实际求值结果记为原码,映射后的结果记为补码。我们先分析下实际的求值结果和映射后的结果:
- 发现原码为0和正数时,补码正确,即原码为0和正数时,原码等于补码;
- 原码为负数时,补码错误,即原码为负数时,原码不等于补码。

问题来了?原码为负数时,补码(如6)怎么转换成原码(如-4)?
答: 谜底就在谜面上,你直接看圆盘不就好了,圆盘上都标注了,圆盘内外侧的数字就是我们原码和补码的映射表。
问题又来了?圆盘上的映射怎么来的?
答:通过补数变换得到的,即原码为负数时,补码 + |原码| = 模,也即原码为负数时,补数 + |原码| = 模,在1.1小节中,我们提到了 a的补数 = 模 - a(a>=0);,
综上:原码为负数时,补码 + |原码| = 模
二、 二进制里的花花世界
宏观世界搞定了,看看微观世界,十进制搞完了,看看二进制。
二进制我们以1Byte(8bit)研究,1 Byte 可以表示256个数(28),即模为256
2.1 原码
1 Byte 范围的内数字为0~255这256个数字。将其置于圆盘上如下:

2.2 补码
- 调整数字范围使其映射到 -128~127 这256个数字:

- 调整圆盘范围,即原码写到圆盘上,补码写到圆盘外,如下:

2.3 补码和原码转换
原码和补码怎么转换呢?
通过1.3节,我们知道如下结论:
- 原码为0和正数时,原码等于补码
- 原码为负数时,补码 + |原码| = 模

- 还记得我们在1.3 小节 文末得到的结论吗?原码为负数时,补码 + |原码| = 模,我们变换下这个等式,即原码为负数时,补码 = 模 - |原码|,按照公式我们计算下:

至此,二进制的原码和补码转换我们也已搞定,即: - 原码为0和正数时,原码等于补码
- 原码为负数时,补码 = 模 - |原码|
2.4 反码
不知道你绕晕了吗?还记得我们的初心吗?怎么用加法替代减法?
2.3 节说原码为负数时,补码 = 模 - |原码|,这玩呢?前面这么多推理就是想用加法替代减法,结果搞了半天回到了原点,还使得计算减法,自己替代自己吗?替代了个寂寞……
不急,稍安勿躁,且听下面道来。
2.4.1 模
细想下 :补数的定义,使得当前数的位数增加1位:
- 假设二进制下,当前为8位,问要使得增加的数最小时,怎么才能使得位数增加1位呢,即由原来的8位变成9位?
答:增加的数为1时最小,此时当前8位数达到了最大,那就是
0b 1111 1111,即0b 1111 1111+0b 0000 0001=0b 1 0000 0000
- 所以我们找到了二进制8位数即将跳变成9位的临界值,即当前8位数的最大值
0b 1111 1111; - 二进制时,一个数变成最大的最快方式,当然是加上该数按位取反后的值。即
0b 1111 1111-0b 0000 0001=0b 1111 1110,看到了吗,0b 1111 1110正好等于0b 0000 0001按位取反的值,那就叫它反码吧,即原码为负数时,反码为原码数据位按位取反,注意这里是数据位,最高位为符号位“为使得定义一致和完整,我们补充:原码为0和正数时,原码等于反码。

- 我们来求下 模

- 如上图所示,原码为负数时,模 (256) = 8bit最大值 + 1 , 8bit最大值 = 原码的绝对值 + 反码,结合之前的 原码为负数时,补码 = 模 - |原码| 得到:

至此,1 Byte 的数据我们通过补码的形式用加法替代了减法。计算机语言内的整数类型比如java的int (4Byte)、long(8Byte)都是如此。
三、总结
为了使用加法替代加法,我们先后引入了补数、模、原码、补码、反码等概念:
- 圆盘代表数字是有范围的,该范围的大小即为模,并且会首尾相连。计算机1 Byte、4Byte、8Byte天然会限定数据的范围。数据范围限定后,数据一直累计下去一定会产生数据溢出(即进位丢失),从而结束当前轮回,开始下一轮回;
- 圆盘内的数字是原码,圆盘外的数字是补码,补码也是模内的无符号整数。注意,反码 + 1只是求得补码的一种方式,并非补码的定义;
- 原码为0和正数时,原码等于反码等于补码;
- 原码为负数时,反码为原码数据位按位取反。
相关文章:
深入理解计算机中的补码、反码、原码
问题: 我们每天用的钟表,其实只有1~12这12个数字,但我们日常会说13点、17点之类的。 问:13点在钟表上哪个位置? 答:很简单嘛,1点的位置。 你不觉得奇怪吗,为啥13点会和1点在同一个位…...
Scratch教学作品 | 白水急流——急流勇进,挑战反应极限! ♂️
今天为大家推荐一款刺激又好玩的Scratch冒险作品——《白水急流》!由AgentFransidium制作,这款作品将带你体验惊险的急流救援任务,帮助那位“睡着的疯狂人”安全穿越湍急水域!想要挑战自己的反应极限?快来试试吧&#…...
Px4 V2.4.8飞控Mavlink命令控制说明
首先,可以使用两种方法连接飞控,使用虚拟机(LINUX)或使用地面站(QGC)连接。 在px4的代码文件位置打开命令终端,输入连接命令: ./Tools/mavlink_shell.py 在控制台使用help来获取所有…...
Linux(Ubuntu24.04)源码编译安装VTK7.1.1记录
VTK(Visualization Toolkit)是一个开源的3D可视化开发工具包,用于开发可视化和图形处理应用程序。VTK提供了一系列的算法和工具,用于创建、渲染和处理复杂的3D图形和数据。VTK由C编写,并提供了Python、Java和Tcl等语言…...
【Go学习】-01-4-项目管理及协程
【Go学习】-01-4-项目管理及协程 1 项目管理1.1 包1.1.1 包的基本概念1.1.2 包的导入1.1.3 包的导入路径1.1.4 包的引用格式 1.2. go mod1.2.1 项目中使用 2 协程并发2.1 并发2.2 Goroutine2.2.1 使用2.2.2 GMP2.2.2.1 Golang “调度器” 的由来2.2.2.2 Go 语言的协程 goroutin…...
ES_如何设置ElasticSearch 8.0版本的匿名访问以及https_http模式的互相切换
总结: 设置匿名访问,只需要设置xpack.security.authc.anonymous.username和xpack.security.authc.anonymous.roles参数就行,设置好后,可以匿名访问也可以非匿名访问,但是非匿名访问的情况下必须保证用户名和密码正确 取…...
PySide6 SQLite3 做的 电脑组装报价系统
一、数据库结构说明 1. 配件类别表 (component_categories) 字段名类型说明约束category_idINTEGER类别IDPRIMARY KEY, AUTOINCREMENTcategory_nameTEXT类别名称NOT NULL, UNIQUEdescriptionTEXT类别描述 2. 配件表 (components) 字段名类型说明约束component_idINTEGER配件…...
逻辑回归(Logistic Regression) —— 机器学习中的经典分类算法
1. 逻辑回归简介 逻辑回归是一种线性分类模型,常用于二分类问题。它通过学习特征权重,将输入映射为0 到 1 之间的概率值,并根据阈值将样本归入某一类别。逻辑回归使用Sigmoid 函数将线性结果转化为概率。 尽管名字中有“回归”,…...
【数据库系统概论】数据库完整性与触发器--复习
在数据库系统概论中,数据库完整性是指确保数据库中数据的准确性、一致性和有效性的一组规则和约束。数据库完整性主要包括实体完整性、参照完整性和用户定义完整性。以下是详细的复习内容: 1. 数据库完整性概述 数据库完整性是指一组规则,这…...
【机器学习:一、机器学习简介】
机器学习是当前人工智能领域的重要分支,其目标是通过算法从数据中提取模式和知识,并进行预测或决策。以下从 机器学习概述、有监督学习 和 无监督学习 三个方面进行介绍。 机器学习概述 机器学习定义 机器学习(Machine Learning࿰…...
网关的主要类型和它们的特点
网关,作为网络通信的关键节点,根据其应用场景和功能特点,可以分为多种类型。 1.协议网关 特点: • 协议转换:协议网关的核心功能是转换不同网络之间的通信协议。例如,它可以将IPv4协议的数据包转换为IPv6协…...
NDA:Non-Disclosure Agreement
NDA 是 Non-Disclosure Agreement 的缩写,中文通常翻译为“保密协议”或“非披露协议”。其含义是:在协议约束下,协议的签署方有义务对协议中规定的信息或内容保密,不能向协议之外的第三方披露。 通常,NDA适用于以下场…...
方正畅享全媒体新闻采编系统 imageProxy.do 任意文件读取漏洞复现(附脚本)
0x01 产品描述: 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、…...
OpenHarmony通过挂载镜像来修改镜像内容,RK3566鸿蒙开发板演示
在测试XTS时会遇到修改产品属性、SElinux权限、等一些内容,修改源码再编译很费时。今天为大家介绍一个便捷的方法,让OpenHarmony通过挂载镜像来修改镜像内容!触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,树…...
代理模式和适配器模式有什么区别
代理模式(Proxy Pattern)和适配器模式(Adapter Pattern)是两种结构型设计模式,它们看似相似,但在设计意图、使用场景以及功能上有一些显著的区别。下面是它们的主要区别: 1. 目的与意图 代理模…...
2025年度全国会计专业技术资格考试 (甘肃考区)报名公告
2025年度全国会计专业技术资格考试 (甘肃考区)报名公告 按照财政部、人力资源和社会保障部统一安排,2025年度全国会计专业技术初级、中级、高级资格考试报名即将开始,现将甘肃考区有关事项通知如下: 一、报名条件 …...
ansible-playbook 搭建JDK
文件目录结构 main.yml #首先检测有无java,没有才会安装,有了就直接跳过 - name: Create installation directoryfile: path/var/www/ statedirectory- name: Check javashell: . /etc/profile && java -versionregister: resultignore_errors…...
数据结构(ing)
学习内容 指针 指针的定义: 指针是一种变量,它的值为另一个变量的地址,即内存地址。 指针在内存中也是要占据位置的。 指针类型: 指针的值用来存储内存地址,指针的类型表示该地址所指向的数据类型并告诉编译器如何解…...
杰盛微 JSM4056 1000mA单节锂电池充电器芯片 ESOP8封装
JSM4056 1000mA单节锂电池充电器芯片 JSM4056是一款单节锂离子电池恒流/恒压线性充电器,简单的外部应用电路非常适合便携式设备应用,适合USB电源和适配器电源工作,内部采用防倒充电路,不需要外部隔离二极管。热反馈可对充电电流进…...
webpack5基础(上篇)
一、基本配置 在开始使用 webpack 之前,我们需要对 webpack 的配置有一定的认识 1、5大核心概念 1)entry (入口) 指示 webpack 从哪个文件开始打包 2)output(输出) 制视 webpack 打包完的…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
