详解原码、反码、补码——深入理解补码

2023-11-19

  学过计算机原理的人都知道原码、反码、补码,但是有多少人知道为什么会有这三种码呢,这三种码又是用来干嘛的呢。
  众所周知,在计算机的世界只有01,那么显然所有的数都得转成二进制,这样计算机才能够理解。如何将一个十进制的数转成二进制就不说了,说下原码,正数的原码就是十进制转成二进制得到的二进制值,而负数是对应的正数转成二进制得到的二进制值,然后将最高位(符号位)置为1表示这是一个负数,如-10:10001010。

1. 原码

  计算机进行算术运算时为了简单效率所以要求能够使用加法代替减法,如1-1==1+(-1)==0,那么我们先看看原码能不能实现这种需求。
示例:

计算76-10==66
   十进制     二进制
   76        01001100
 +  -10       10001010
---------------------
   66        11010110(-86)
2. 反码

  从上面算出的结果可见原码是无法完成对减法的运算需求的,那么由于1-1==1+(-1),所以人类又找到了一个看似能够解决这个问题的解决方法——反码,即将负数的符号位不变其余位取反。下面我们再看看反码能不能解决问题。
示例1:计算15-125

计算15-125==-110
   十进制     二进制原码    二进制反码
   15        00001111    00001111
 +  -125      11111101    10000010
---------------------------------
   -110      11101110    10010001
得到10010001(反码)==11101110(原码)==-110,正确。注意:使用反码计算得到的结果也是反码,需要再次转换成原码。

示例2:计算76-10

计算76-10==66
   十进制     二进制原码    二进制反码
   76        01001100    01001100
 + -10       10001010    11110101
---------------------------------
   66        01000010    101000001==01000010  
这里得到的值超过8bit,所以最高的1需要丢弃,丢弃后需要在最低位+1,得到01000010(反码)==01000010(原码)==66,正确。

示例3:计算1-1

计算1-1==0
   十进制     二进制原码    二进制反码
   1         00000001    00000001
 + -1        10000001    11111110
---------------------------------
   0         10000000    11111111  
得到11111111(反码)==10000000(原码)==-0,-0?通过反码计算会出现+0和-0,一个0对应了两个码,显然是不合理的。

  从上面三个例子可以看出使用反码进行减法运算时存在两个问题:
  1. 当计算结果溢出时需要额外进行+1操作,使得运算多了一步,效率降低
  2. 0存在+0和-0两种存在方式,不方便理解

3. 模与互补、同余

  在看补码之前,先介绍三个概念——模、补数、同余。我们从现实生活举例来看:

  • 我们将一个时钟的分针往前拨20分钟,和往后拨40分钟,得到的结果是一样的。
  • 把你的属年(属猴)往后退5年,和往前进7年,一样都是属兔。
  • 把数字 87,减去 25,和加上 75,在不考虑百位数的条件下,得到的结果都是62。

  上述几组数字,有这样的关系:
    20 + 40 = 60
    5 + 7 = 12
    25 + 75 = 100
  式中的 60、12 和 100,就是“模”。
  式中的 20和40、5和7,以及25和75,就是一对对“互补”的数字。
  而且20,80,140在模是60的情况下就是互为“同余”的数字。
  通俗解释下模、补数、同余的概念:

  • :就是一个轮回,比如分针转一圈,十二生肖一轮等等。
  • 互补 :一个数值针对某个模的互补值就是这个数值加上或者减去多少能够等于模,或者等于模的同余值。
  • 同余 :一个数值加上或者减去模的整数倍得到的所有数值即为该数值的同余值(也就是除上模,余数是一样,所以叫同余),0是模的同余,-模也是模的同余。

  理解了什么是模,什么是互补、什么是同余,那么如果给一个模,以及一个值a,如果计算a的补数(与a互补的值)呢,其实很简单,只需要拿模-a即可,计算同余值可以直接加上或者减去模的整数倍即可。

4. 那么互补的值有什么用呢?

  如果我们在进行减法运算时,用与减数互补的值代替减数与被减数进行加法运算会发生什么呢?废话不多说,看示例。
示例1:在分钟刻度下,计算55分钟往后拨动34分钟,转化成数学计算就是:55-34

被减数      55
减数        34
减数补数   60-34==26
最终结果     55+26==81
---------------------
用减数补数代替减数得到结果为81,81在分钟刻度盘上正好是21,也就是81是21的同余值,和55-34是一样的。注意:这里涉及到类似上面的87+75的情况,即忽略了进位。

示例2:在十二生肖中,计算猴年往后退11年,转化成数学计算就是:9-11

被减数      9
减数        11
减数补数   12-11==1
最终结果     9+1==10
-------------------
用减数互补值代替减数得到结果为10,10对应到十二生肖正好是鸡,和猴年往后退11年是一样的,所以得到的也是一个同余值。

  从上面的示例可以看出,使用互补值计算出的结果与实际值其实是同余的关系。

5. 二进制的模

  上面看了分钟刻度盘的模,十二生肖的模,以及两位整数的模,那么对于一个8bit的字节的模是多少呢?
  分钟刻度盘的模为什么是60?是因为他的值是从1-59,总共60个值,十二生肖以及两位整数也是一样的,所以我们只需要看看一个8bit的字节的所有取值一共是多少个就是他的模,显示8个bit可表示的最小值是00000000==0,最大值是11111111==255,那么从0到255一共是256个值,所以一个8bit的字节的模就是256了。但是其实在计算机中为了能够表示负数,所以讲8bit的字节的最高位设为符号位,0表示整数,1表示负数,所以能够表示数值的也就只有7bit,如果我们忽视符号位,那么剩下7bit的模就是128,而不是256了。下面在计算时我们会直接使用128而非256!

6. 使用互补值进行二进制的减法计算

  下面我们就来看看如果使用互补值来进行二进制的减法计算,我们先来看一个公式:假设模式M,我们计算X-Y,然后我们使用减数的补数来计算,看看下面的换算:

X-Y == X+(M-Y) == X+((M-1)-Y+1)

  下面我们来看示例,这个公式在下面会用到的。

示例1:计算15-125

           十进制          二进制
被减数      15             0001111
减数        125            1111101
减数补数   128-125==3     0000011
最终结果     18             0010010
------------------------------------
得到0010010==18,在模式128的情况下,18正好是-110的同余值,跟上面现实的例子是一样的!

示例2:计算76-10

           十进制          二进制
被减数      76             01001100
减数        10            00001010
减数补数   256-10==246   11110110
最终结果     322    101000010
------------------------------------
得到101000010==322,在模式256的情况下,322正好是66的同余值,结果还是一样!

  从上面两个例子我们应该可以看出,如果我们使用减数的补数进行加法运算,那么得到的结果就是一个与正确结果同余的值。在现实生活中,我们可以直接把两个同余的值看做是相同的,例如分钟20和分钟80完全就是一样的,那么在计算机里我们可以这么假设吗?答案是可以的,看下面。
  试想当计算机使用一个7bit的空间保存一个数值时是如何保存的,比如18,我们可以这么推算,首先分配一个7bit的空间,每个bit上的值都是0,那么如何表示18呢?我们可以这样理解:往这个7bit的空间内进行18次加1操作,满2就进1,最终就会得到0010010。那么如何表示-110,我们可以理解为往这个7bit的空间内进行110次减1操作,一开始全是0,那么如何减1呢?很简单直接减成1111111即可,可以这样理解,分钟在0刻度,你往后拨一下就会指向59,这里也是这个道理,所以连续减110次,就会得到0010010,根18是一样的,所以在计算机看来18和-110是一样的。
也就是说15-125 == 15+(128-125) == 15+(127-125+1) (上面的公式),也就是说-125被127-125+1代替了,那么127-125+1(M-)又是什么?

7. 补码

  上面一路走来终于证明了使用补数可以代替减法,下面我们要解决的问题是M-1-Y+1是啥。
我们直接看二进制如何计算M-1-Y+1。
示例:计算M=128,Y=110

     十进制   二进制
 M-1  127   1111111
 -Y   110   1101110
            0010001
--------------------
M-1换算成二进制就是N位1,那么N位1减去任何一个N位的二进制是啥呢?其实就是按位取反!因为遇到0,1-0==1,取反,遇到1,1-1==0,取反,所以整体就是按位取反,也就是反码。

 +1   1     0000001
            0010010
 ------------------
所以总体就是在110的二进制基础上按位取反然后加1,也就是110的反码加1。

  看了上面的示例,应该知道M=128,Y=110,M-1-Y+1就是Y的反码加1,也就是说,如果我们需要计算X-Y,只需要计算X+(Y的反码+1),由于我们得出这个结论是使用补数替代减法得到的,所以Y的反码+1就被叫做Y的补码
  到这里我们知道了110的补码,上面我们介绍了计算机使用1字节的最高位表示符号位,1表示负数,所以-110的最高位是1,由于在使用补码进行减法运算过程中最高位并不参与运算,所以这个最高位应该是固定不动的,所以负数的反码补码最高位始终都是1。也就得到了-110的补码是:10010010。对于正数,符号位是0,那么反码补码最高位就始终是0,而且对于正数在计算时也无需使用其补码进行操作,但是为了统一都是用补码,所以定正数的反码补码都等于原码。
  根据补码的计算过程有些文章会说一个负数X的补码对应的值==2^n-|X|,理解了上面的过程这个公式就自然懂了,不过这个公式没啥用,也没必要记。
  到这里终于把补码的来历说清楚了,至少我自己是明白了,但愿读者也可以明白吧!

一些补码的其他知识

  上面我们看了7bit的模式128,也就说是能表示0-127共128个数值,加上最高位的符号位就成了-127-127共计255个数值,因为没有-0这个数字。但是实际对于计算机来说8bit的空间是可以表示256个数字的,那么还有一个数字是啥呢?正是:10000000(注意:这是补码,因为计算机都存的补码)。我们可以试着计算下10000000的原码,可以得到10000000的原码就是10000000,也就是-0,但是如果存在+0和-0两个计算机码对应一个值(+0和-0都是0),那么显然是没必要的,而且还会造成混乱,所以人为的规定10000000表示-128。所以一个8bit的空间可以表示的数字就是从-128到127了,而不是-127-127!

8. 参考文章

感谢下面这些文章帮助我理解补码:
原码, 反码, 补码 详解
原码、反码和补码

欢迎大家点评讨论!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详解原码、反码、补码——深入理解补码 的相关文章

  • 原码反码补码的概念,以及原码反码的表示形式

    本文主要讲解计算机的原码 反码和补码 的概念 以及原码反码的表示形式 以及原码反码补码之前如何相互转换 还有计算机中数字是怎么样存储的 原码 假设机器字长为n 原码 自然二进制码 是一种计算机中对数字的二进制定点表示方法 原码表示法在数值前
  • 计算机网络笔记(四):Socket编程

    文章目录 前言 Socket API 函数 WinSock为例 数据解析 网络字节顺序 解析服务器IP地址 端口号 解析协议号 TCP UDP客户端软件流程 服务器软件设计 前言 几种典型的应用编程接口 Berkeley UNIX操作系统定
  • 关系代数之连接 (Join)和除(Division)

    关系代数之连接 Join 和除 Division 数据库技术中这两个概念 对初学者而言 理解比较困难 本文对此进行深入浅出的解释 连接 Join 联接 定义 从两个关系的笛卡尔积中选取属性间满足一定条件的元组 记作 其中A和B分别为R和S上
  • 如何最高效实现手机~电脑端文件传输?

    平常使用电脑办公的时候 经常会有把手机上的文件传到电脑或把电脑上的文件分发给局域网 内网 的各个伙伴的情况 通常我们会选择使用QQ或微信的文件传输功能来实现 但是当文件比较大 比较多时 就无法发送了 再者每次通过文件助手来发送文件时 其本质
  • 锁(Lock)、内存屏障(Memory barrier)与 缓存一致性( Cache coherence)

    文章目录 前言 Optimization Barrier Memory barrier Cache coherence 总结 参考资料 前言 在应用层 关于锁的使用大家应该都很熟悉了 作用就是为了保护共享变量不被同时操作而导致无法预测的情况
  • 虚拟内存和分页文件

    分页文件 也就是虚拟内存文件 或叫做交换文件 Windows 2000 XP 2003中的分页文件名为pagefile sys 虚拟内存有什么用 内存在计算机中的作用很大 电脑中所有运行的程序都需要经过内存来执行 如果执行的程序很大或很多
  • spring-boot后端解决跨域问题

    代码 import cn hutool log Log import cn hutool log LogFactory import com alibaba fastjson JSONObject import org springfram
  • Linux系统启动分析

    文章目录 大体流程分析 一 BIOS 1 1 BIOS简介 1 2 POST 二 BootLoader GRUB 2 1 What s MBR 2 2 What s GRUB 2 3 boot img 2 4 core img lzma d
  • Windows记事本编码反汇编分析

    转载自 liam page 网上有一个流传多年的段子 这个段子大致是说 若你在简体中文版本的 Windows 系统下 用系统自带的记事本程序 以默认的 ANSI 编码保存 联通 两个字 那么重新打开后 联通 二字就消失了 如果我没记错的话
  • Redfish协议测试工具–Postman

    1 工具和资料获取 2 简单使用说明 1 GET类举例 2 PATCH类举例 3 常见命令 1 工具和资料获取 Postman工具获取 服务器Redfish接口说明文档 使用前必读接口文档中 适用的产品 查看自己的服务器是否支持此协议 2
  • uthash

    在软件开发中 不可不免的会使用到hash表 hash表的优点这里就不说了 以下介绍一个hash表的C实现 uthash是用宏实现的 使用的时候非常方便 只用包含uthash h即可 Uthash的三个数据结构 1 typedef struc
  • Matlab2021a安装教程

    目录 一 资源文件 二 安装 一 资源文件 名称 Matlab R2021a 大小 17 11GB 语言 简体中文 安装环境 Win10 64位下载链接 https pan baidu com s 1OIyhX8kpVfydlo aOnbT
  • 计算机基础内容——网络基础

    网络基础 设备是如何上网的 网卡 有线 无线 内置天线 网线接口RJ45 usb转RJ45 交换机 路由器 外置天线 天线棒 光猫 宽带运营商 不同的宽带运营商之间是互通的 路由器发出的wifi信号 2 4GHz wifi 5 0GHz w
  • 字符编码和字符集有什么区别?Unicode是什么,和UTF-8是什么关系?你想知道的都在这篇文章了

    前言 想必大家编写代码时肯定和我一样 也遇到过汉字乱码的问题 特别是 有时候和上下游对接接口 不能统一编码格式的话 一堆乱码问题 让人头皮发麻 那么为什么会有这么多的乱码问题 什么是字符编码 什么是字符集 他们之间有什么区别和联系 什么是
  • 笔记总结备份

    目录 文章目录 目录 前言 版本控制 常用git 命令 操作系统 系统 机器数 时间管理 早期的 Linux 时间系统 中断 内存管理 内存分区 malloc申请一块内存的背后原理 RTOS 系统栈和协议栈 寄存器 磁盘调度算法 虚拟内存
  • 图解Git

    基本用法 上面的四条命令在工作目录 暂存目录 也叫做索引 和仓库之间复制文件 git add files 把当前文件放入暂存区域 git commit 给暂存区域生成快照并提交 git reset files 用来撤销最后一次git add
  • FLOPS、TOPS和FLOPs的区别

    FLOPS 即每秒浮点运算次数 是每秒所执行的浮点运算次数 Floating point operations per second 缩写 FLOPS 的简称 被用来评估电脑效能 FLOPs 注意s小写 是floating point op
  • 字符编码悉知

    1 查看windows系统代码页 代码页是字符集编码的别名 也有人称 内码表 早期 代码页是IBM称呼电脑BIOS本身支持的字符集编码的名称 当时通用的操作系统都是命令行界面系统 这些操作系统直接使用BIOS供应的VGA功能来显示字符 操作
  • 计算机中的二进制表示-4和5

    十进制 二进制 5 00000000 00000000 00000000 00000101 4 11111111 11111111 11111111 11111100 负数的二进制如何得出 相信正数的二进制表示大家都懂 但是这个 4怎么来的
  • 计算机基础:网络基础

    一 网线制作 1 制作所需要工具 网线 网线制作标准 2 水晶头使用 3 网线钳使用 4 视频教学 网线制作 二 集线器 交换机介绍 1 OSI七层模型 Open System Interconnect 即开放系统互连参考模型 是由 ISO

随机推荐

  • Linux 磁盘命令工具 比df更好用

    对于分析磁盘使用情况 有两个非常好用的命令 du 和 df 简单来说 这两个命令的作用是这样的 du 命令 它是英文单词 disk usage 的简写 主要用于查看文件与目录占用多少磁盘空间 df 命令 它是英文单词 disk free 的
  • python爬取证券之星网站

    周末无聊 找点乐子 coding utf 8 import requests from bs4 import BeautifulSoup import random import time 抓取所需内容 user agent Mozilla
  • 安卓逆向学习-Crack01 学习记录

    Crack01 学习记录 要感谢京峰教育 资料下载 https download csdn net download m0 47210241 85053839 利用jadx gui打开 分析代码 package com zhy editVi
  • nodejs封装api

    安装了nodeJs 执行 安装淘宝镜像 npm install g cnpm registry https registry npm taobao org 安装 yarn 我使用这个 淘宝镜像总是莫名其妙各种bug npm install
  • aix安装 php,CNESA

    aix安装samba服务器可以使用两种方式安装 一种是使用rpm包进行安装 一种是使用源码编译安装 一 使用samba的rpm包进行安装 1 下载samba的rpm包 下载地址为http www bullfreeware com searc
  • C++笔记--线程间共享数据

    当线程在访问共享数据的时候 必须制定一些规矩 用来限定线程可访问的数据位 还有 一个线程更新了共享数据 需要对其他线程进行通知 从易用性的角度 同一进程中的多个线程进行数据共享 错误的共享数据使用是产生并发bug的一个主要原因 当涉及到共享
  • 为什么训练集用fit_transform()而测试集用transform()及sklearn.feature_extraction.text.CountVectorizer API详解

    真正讲明白的 https blog csdn net yyhhlancelot article details 85097656 API https scikit learn org stable modules generated skl
  • mysql+mybatis 批量插入与批量更新

    首先批量更新需要增加 数据库的链接必须加上但是数据库连接必须加上 allowMultiQueries true 属性 不然会报错 You have an error in your SQL syntax check the manual t
  • 各种源码下载地址(目前只有ffmpeg和nginx,libcurl,RapidJSON 文档)

    各种源码下载地址 目前只有ffmpeg和nginx libcurl RapidJSON 文档 ffmpeg源码下载地址 http ffmpeg org download html releases nginx源码下载地址 http hg n
  • H5监听移动端物理/浏览器返回键

    JavaScript没有监听物理返回键的API 所以只能使用 popstate 事件监听 工具类如下 export function handleBrowserGoBack back console log back pushHistory
  • 论文阅读——基于深度学习智能垃圾分类

    B Fu S Li J Wei Q Li Q Wang and J Tu A Novel Intelligent Garbage Classification System Based on Deep Learning and an Emb
  • su命令切换用户输入密码后,提示:鉴定故障

    在终端通过su命令切换用户输入密码后 提示 鉴定故障 这是因为在安装linux系统时未设置root用户密码造成的 需要重新设置密码后再切换用户 具体操作命令如下 设置root用户密码 sudo passwd root 切换用户 su
  • 三步搞定ABAP DOI操作EXCEL

    ABAP可以使用OLE与DOI两种方式实现操作EXCEL 使用OLE时 每个单元格的值和样式都需要写代码实现 特别是对于不规则的格式 代码量巨大 而DOI是从服务器已经上传的EXCEL模板中下载模板然后打开修改实现数据保存 当然 也可以直接
  • springboot中的kafka的KafkaTemplate的配置类

    package com lf report utils import org apache kafka clients producer ProducerConfig import org apache kafka common seria
  • opencv 智能答卷识别系统(一)

    目标 这里是2 智能答卷之别系统二 识别答卷答案 识别准号证号码 识别姓名 识别试卷类别 试卷是有标记的 如试卷上方的黑框 排序结构 使用c 的标准排序算法 struct Ruley bool operator const Rect a1
  • 华为OD机试真题-座位调整-2023年OD统一考试(B卷)

    题目描述 疫情期间课堂的座位进行了特殊的调整 不能出现两个同学紧挨着 必须隔至少一个空位 给你一个整数数组 desk表示当前座位的占座情况 由若干 0 和 1 组成 其中 0 表示没有占位 1 表示占位 在不改变原有座位秩序情况下 还能安排
  • C#获取当前路径 -- 7种方法

    目录 一 代码 二 路径区别 三 参考文献 一 代码 推荐使用第3种 internal static class Program static void Main 获取模块的完整路径 string path1 System Diagnost
  • C++:入门学习C++,它在C的基础上做了哪些修改?

    文章目录 命名空间 缺省参数 函数重载 引用 引用作为函数返回值 引用的收益 引用和指针的区别 引用和指针的对比 内联函数 内联函数的特性 内联函数和宏的关系 指针空值问题 命名空间 首先看这样的代码 include
  • vue canvas typescript 绘制时间标尺

    项目中有个需求 将对象一天内对应的不同的状态在时间轴上显示出来 调研的方案有5种 1 时间轴用div画 时间轴上遮罩的状态改变则改变时间轴div本身的颜色 2 时间轴用div画 时间轴上的遮罩用div画 状态改变则改变遮罩div的颜色 时间
  • 详解原码、反码、补码——深入理解补码

    学过计算机原理的人都知道原码 反码 补码 但是有多少人知道为什么会有这三种码呢 这三种码又是用来干嘛的呢 众所周知 在计算机的世界只有01 那么显然所有的数都得转成二进制 这样计算机才能够理解 如何将一个十进制的数转成二进制就不说了 说下原