什么是原码和补码

补码的本质确实是模运算(Modular Arithmetic),这是理解补码为何能统一加减法的核心数学原理。下面用最通俗的语言和例子解释清楚:
—### 1. 先理解什么是“模运算”- 模运算就是“周期性计数”,比如钟表: - 钟表只有12小时,超过12就重新开始(模12)。 - 例如:15点 → 15 - 12 = 3点(15 mod 12 = 3)。 - 负数例子:如果现在是3点,8小时前是几点? - 直接减:3 - 8 = -5 → 负数无法直接表示在钟表上。 - 用模运算转换:-5 + 12 = 7 → 7点(相当于-5 ≡ 7 mod 12)。—### 2. 计算机的“模”是什么?- 计算机的二进制位数是固定的(比如8位、32位),天然适合模运算。 - n位二进制的模是 (2^n): - 例如:8位二进制的模是 (2^8 = 256)。 - 所有运算结果超出位数时,自动丢弃高位(相当于取模)。—### 3. 补码的本质:用模运算表示负数- 核心思想:将负数转换为一个等效的正数(通过模运算),让加减法统一为加法。 - 例如:在8位系统中,如何表示 -5? - 计算:(256 - 5 = 251) → 251 的二进制是 1111 1011,这就是 -5 的补码。 - 验证5 + (-5) = 0 → 补码运算: 5(0000 0101) + 251(1111 1011) = 256(1 0000 0000) → 丢弃溢出位 → 0000 0000(0,正确!)—### 4. 为什么补码能统一加减法?- 所有负数都表示为“模 - 绝对值”: - 在8位系统中,-x ≡ (2^8 - x)(即 (256 - x))。 - 加减法等价于模运算: - 例如:A - BA + (256 - B) mod 256。 - 硬件自动丢弃溢出位,结果自然正确。#### 案例:用钟表理解补码- 问题:钟表时间是3点,如何表示“-5小时”? - 直接减:3 - 5 = -2 → 无法直接表示。 - 用模12转换:-5 ≡ 12 - 5 = 7 → 加7小时: - 3点 + 7小时 = 10点 → 等价于3点 -5小时 = 10点(正确,因为钟表是循环的)。 - 计算机同理:用补码将负数转换为等效正数,运算后自动取模。—### 5. 补码的数学公式- 对于n位二进制,补码的定义: - 正数:直接表示。 - 负数:(-x) 的补码 = (2^n - x)。- 运算规则: - (A + (-B)) ≡ (A + (2^n - B)) ≡ (A - B) mod (2^n)。#### 案例:8位系统中计算 10 - 71. 转换为补码加法:10 + (-7)2. 计算补码: - -7 的补码 = 256 - 7 = 249 → 二进制 1111 1001。3. 运算0000 1010(10) + 1111 1001(-7的补码) = 1 0000 0011 → 丢弃溢出 → 0000 0011(3,正确!)—### 6. 补码的直观优势1. 符号位即数值: - 最高位是1时,代表这个数是“模 - 正数”。 - 例如:8位补码 1000 0001 = (256 - 127 = 129) → 实际表示 -127。2. 硬件无需区分正负: - 加减法统一用加法器完成,符号位直接参与运算。3. 自然处理溢出: - 运算结果超出位数时,丢弃高位即等效于取模。—### 总结- 补码是模运算在计算机中的具体应用: - 负数 -x 被表示为 (2^n - x)。 - 加减法统一为加法,结果自动取模。- 记住这个公式: - 在n位系统中-x ≡ (2^n - x)(这就是补码的好的!这次我们彻底讲透,用最直观的方式,结合数学原理和实际案例,保证你理解并记住。


终极目标:计算机如何用二进制表示负数,并正确运算?

关键矛盾:
  • 计算机只能处理 0 和 1,没有“负号”
  • 必须用纯二进制数同时表示正数和负数
  • 加减法必须统一用加法电路完成(否则硬件成本高)。

一、原码:直观但缺陷明显

定义
  • 最高位为符号位:0 正,1 负。
  • 其他位为数值的绝对值
  • 例子(8位):
    • +50 000 0101(符号位+5的绝对值)
    • -51 000 0101(符号位+5的绝对值)
致命问题
  • 直接运算会出错
    # 计算 5 + (-5):0000 0101  (+5)
    + 1000 0101  (-5)
    = 1000 1010  (十进制是 -10,但正确结果应为 0!)
    
  • 双零问题0000 0000(+0)和 1000 0000(-0)同时存在。

二、反码:试图改进运算

定义
  • 正数:与原码相同。
  • 负数:符号位不变,数值位取反(0→1,1→0)。
  • 例子(8位):
    • -51 111 1010(原码1000 0101的数值位取反)
运算尝试
  • 计算 5 + (-5)
      0000 0101  (+5的反码)
    + 1111 1010  (-5的反码)
    = 1111 1111  (反码的-0,十进制为 0,但有两个零)
    
  • 问题
    1. 双零问题依然存在0000 00001111 1111)。
    2. 需要处理进位:如果运算后最高位有进位,需循环加回结果末尾。

三、补码:彻底解决问题的终极方案

定义
  • 正数:与原码相同。
  • 负数:反码 + 1(等价于用模运算表示负数)。
  • 例子(8位):
    • -5 的补码:
      原码:1000 0101
      反码:1111 1010  (数值位取反)
      补码:1111 1011  (反码 +1)
      
补码的数学原理
  • 本质是模运算(钟表原理)

    • 假设用 8 位二进制(范围 0~255),模为 256。
    • 负数 -x 等价于 模 - x
      • -5256 - 5 = 251 → 二进制 1111 1011(这就是补码)。
  • 运算自动溢出

    # 计算 5 + (-5):0000 01015的补码)
    + 1111 1011-5的补码)
    = 1 0000 0000  (结果超出 8 位,最高位 1 被丢弃)
    → 最终结果:0000 00000,正确!)
    
补码的绝对优势
  1. 统一加减法:减法 A - B 等于 A + (-B) 的补码加法。
  2. 符号位直接参与运算:无需额外判断符号。
  3. 单零问题:只有 0000 0000 表示 0。
  4. 硬件电路简单:只需一个加法器,无需减法器。

四、补码的深度案例解析

案例1:8位补码范围
  • 最大正数0111 1111 → +127。
  • 最小负数1000 0000 → -128。
  • 为什么是 -128?
    • 8位补码中,1000 0000 没有对应的原码,直接规定为 -128。
    • 数学上:1000 0000 = -128(因为 -128 + 127 = -1,而 1000 0000 + 0111 1111 = 1111 1111(-1的补码))。
案例2:补码的快速转换
  • 已知补码求十进制

    • 补码 1111 1011
      1. 符号位为 1 → 负数。
      2. 数值位取反加1:1111 1011 → 取反 0000 0100 → 加1 → 0000 0101 → 绝对值 5。
      3. 结果:-5。
  • 十进制转补码

    • -20 的8位补码:
      1. +20 的原码:0001 0100
      2. 数值位取反:1110 1011
      3. 加1:1110 1100 → 这就是 -20 的补码。
案例3:跨零运算
  • 计算 3 - 5(等价于 3 + (-5)):
    3的补码:0000 0011
    -5的补码:1111 1011
    相加:0000 0011
    + 1111 1011
    = 1111 1110  (结果的补码)
    → 转十进制:符号位1 → 负数,数值位取反加10000 0010-2(正确!3-5=-2)。
    

五、为什么必须用补码?

  1. 硬件成本:补码让加减法统一用加法器实现,无需额外减法电路。
  2. 运算一致性:符号位直接参与运算,无需特殊处理。
  3. 单零问题:避免程序中出现 +0-0 的歧义。
  4. 数学严谨性:补码的本质是模运算,完美契合二进制溢出特性。

终极记忆口诀

  • 原码:看符号,算绝对值(但算不对)。
  • 反码:负数取反,双零还在(运算要加回进位)。
  • 补码:负数取反加一,符号直接运算(一切问题解决)。

总结表格

编码正数表示负数表示零的个数能否直接运算?
原码符号位0+绝对值符号位1+绝对值2个❌ 出错
反码同原码符号位1+数值位取反2个⚠️ 需处理进位
补码同原码符号位1+数值位取反+11个✅ 完美

彻底理解补码后,你就能看透计算机底层的一切数值运算!这就是为什么现代计算机全部使用补码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记项目 day02

一、用户登录接口 请求参数: 用loginDTO来封装请求参数,要加上RequestBody注解 响应参数: 由于data里内容较多,考虑将其封装到一个LoginUser的实体中,用户登陆后,需要生成jwtToken并返回给前端。 登录功…

2025年土木建筑与水利工程国际会议(ICCHE 2025)

2025 International Conference on Civil and Hydraulic Engineering (ICCHE 2025) (一)会议信息 会议简称:ICCHE 2025 大会地点:中国银川 投稿邮箱:icchesub-paper.com 收录检索:提交Ei Compendex,CPCI,C…

运行Spark程序-在shell中运行1

(一)分布式计算要处理的问题 【老师提问:分布式计算要面临什么问题?】 【老师总结】 分布式计算需要做到: 1.分区控制。把大的数据拆成一小份一小份的(分区,分片)让多台设备同时计算…

一文理清人工智能,机器学习,深度学习的概念

目录 一、人工智能的起源与核心范畴(1950-1980) 1.1 智能机器的最初构想 1.2 核心范畴的初步分化 二、机器学习的兴起与技术分化(1980-2010) 2.1 统计学习的黄金时代 2.2 神经网络的复兴与子集定位 2.3 技术生态的形成与AI…

《Effective Python》第1章 Pythonic 思维总结——编写优雅、高效的 Python 代码

《Effective Python》第1章 Pythonic 思维总结——编写优雅、高效的 Python 代码 在编程的世界里,每个语言都有其独特的风格和最佳实践。对于 Python 而言,“Pythonic”已经成为描述遵循 Python 特定风格的代码的代名词。这种风格不仅让代码更易读、更简…

MySQL 事务(二)

文章目录 事务隔离性理论理解隔离性隔离级别 事务隔离级别的设置和查看事务隔离级别读未提交读提交(不可重复读) 事务隔离性理论 理解隔离性 MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行一个事务可能由多条SQL…

代码仓提交分支规范

以下是我部门开发时用的分支规范,参考于Linux社区 Tips 分支命名通常遵循一些最佳实践和规则,以便使分支的用途和内容清晰易懂,就在写一个文档的主题一样。 功能分支 (Feature Branches) 用于开发新功能。 命名格式:feature/功能名…

Google Earth Engine(GEE) 代码详解:批量计算_年 NDVI 并导出(附 Landsat 8 数据处理全流程)

一、代码整体目标 基于 Landsat 8 卫星数据,批量计算 2013-2020 年研究区的 NDVI(归一化植被指数),实现去云处理、数据合成、可视化及批量导出为 GeoTIFF 格式,适用于植被动态监测、生态环境评估等场景。 二、代码分步解析(含核心原理与易错点) 1. 加载并显示研究区边…

Maven 处理依赖冲突

Maven处理依赖冲突 什么是依赖冲突?如何解决?Maven自动处理依赖冲突的规则路径优先原则第一声明优先原则注意 子模块覆盖父模块父模块声明dependency子模块覆盖dependency父模块声明dependencyManagement 子模块覆盖dependency父模块声明dependencyManag…

docker 安装 sqlserver2022 和注意点

一、前言 1、可以直接参考微软官方文档 快速入门:使用 Docker 运行 SQL Server Linux 容器映像,这里主要是说一些注意点和坑 二、安装 1、拉取镜像 docker pull mcr.microsoft.com/mssql/server:2022-latest2、创建挂载目录,这里只是比官方…

Dagster Pipes系列-1:调用外部Python脚本

本文是"Dagster Pipes教程"的第一部分,介绍如何通过Dagster资产调用外部Python脚本并集成到数据管道中。首先,创建Dagster资产subprocess_asset,利用PipesSubprocessClient资源执行外部脚本external_code.py,实现跨进程…

【SQL系列】多表关联更新

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C++进阶学习:STL常用容器--map/multimap容器

1. map 容器基本概念 map 中所有元素都是 pair pair 中第一个元素为 key (键值) 起到索引运用 第二个元素为 value(实值) 所有元素都会根据元素的键值自动排序 本质: map/multimap 属于关联式容器 底层结构是用二…

let,const,var关键字的区别

let,const,var关键字 let,const,var都存在变量提升 它们都存在变量提升但是稍微有点不同 var变量声明会被提升到作用域的顶部,并且会被初始化为 undefinedlet 和 const:变量声明也会被提升到作用域的顶部,但不会被初…

Nuitka 已经不再安全? Nuitka/Cython 打包应用逆向工具 -- pymodhook

pymodhook是一个记录任意对Python模块的调用的库,用于Python逆向分析。 pymodhook库类似于Android的xposed框架,但不仅能记录函数的调用参数和返回值,还能记录模块的类的任意方法调用,以及任意派生对象的访问,基于pyob…

path环境变量满了如何处理,分割 PATH 到 Path1 和 Path2

要正确设置 Path1 的值,你需要将现有的 PATH 环境变量 中的部分路径复制到 Path1 和 Path2 中。以下是详细步骤: 步骤 1:获取当前 PATH 的值 打开环境变量窗口: 按 Win R,输入 sysdm.cpl,点击 确定。在 系…

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(一)

1 目的 物料(例如晶圆)加工在设备中的自动化管理与控制是实现工厂自动化的关键要素。本标准针对半导体制造环境中与设备内部物料处理相关的通信需求进行了规范。本标准规定了在加工单元接收到的指定材料所应适用的加工方法(例如Etch腔室需要Run哪支Recipe)。它阐述了物料加工的…

【Hadoop】集群搭建实战:超详细保姆级教程

🐇明明跟你说过:个人主页 🏅个人专栏:《大数据前沿:技术与应用并进》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Hadoop简介 2、Hadoop集群概念 3、 Hadoop 集…

阿里云人工智能大模型通义千问Qwen3开发部署

本文主要描述阿里云人工智能大模型开源社区ModelScope提供的通义千问Qwen3开发部署。 与阿里云一起 轻松实现数智化 让算力成为公共服务:用大规模的通用计算,帮助客户做从前不能做的事情,做从前做不到的规模。让数据成为生产资料:…

24.(vue3.x+vite)引入组件并动态挂载(mount)

示例截图 组件代码: <template><div><div>{{message }}</div>