火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

计算机中的编码

作者: 作者的头像   吴新雄 , 时间:2025-11-21 19:25:41 , 所有人可见, 阅读  110

1. 为什么需要编码?

计算机底层只能表示0和1,需要一种编码方式来表示负数和执行减法运算。 直接使用原码进行减法,电路设计会非常复杂。补码的出现,成功地将减法运算转换为加法运算,大大简化了CPU的算术逻辑单元(ALU)设计。


2. 核心概念与定义(以8位有符号整数为例)

我们假设用一个字节(8位)来表示一个数。最高位(最左边)为符号位,其余为数值位。 - 符号位: 0 表示正数,1 表示负数。

2.1 原码 (Sign-Magnitude)

  • 定义: 最高位表示符号,其余位表示该数的绝对值的二进制形式。
  • 范围: -127 到 +127 (即 1111 1111 到 0111 1111)
  • 特点: 直观,但存在 +0 和 -0 两种零的表示。
    • +0: 0000 0000
    • -0: 1000 0000

示例: - +5 = 0000 0101 - -5 = 1000 0101

2.2 反码 (Ones' Complement)

  • 定义:
    • 正数的反码与其原码相同。
    • 负数的反码是其对应正数的原码按位取反(包括符号位)。
  • 范围: -127 到 +127
  • 特点: 同样存在 +0 和 -0 的问题。
    • +0: 0000 0000
    • -0: 1111 1111

示例: - +5 = 0000 0101 (原码) -> 0000 0101 (反码) - -5: 1. +5的原码: 0000 0101 2. 按位取反: 1111 1010 3. 所以 -5的反码 = 1111 1010

2.3 补码 (Two's Complement) - 现代计算机标准

  • 定义:
    • 正数的补码与其原码相同。
    • 负数的补码是其反码 + 1。
  • 范围: -128 到 +127 (这是关键优势,比原码和反码多表示一个数)
  • 特点: 解决了 ±0 的问题,统一了零的表示 (0000 0000),并且减法可以变加法。

示例: - +5 = 0000 0101 (原码) -> 0000 0101 (补码) - -5: 1. +5的原码: 0000 0101 2. 按位取反得到反码: 1111 1010 3. 反码 + 1 得到补码: 1111 1011 所以 -5的补码 = 1111 1011


3. 计算与运算方式

3.1 由负数求其补码(快速方法)

  1. 写出该负数绝对值的原码。
  2. 从右向左,遇到第一个1之前,保持所有位不变。
  3. 第一个1之后,将其左边的所有位按位取反。

示例: 求 -12 的补码 (8位) 1. +12的原码: 0000 1100 2. 从右向左,第一个1在从右数第3位:0000 11**00** 3. 这个1左边的位全部取反:1111 01**00** 4. 结果: 1111 0100 (与 反码+1 方法结果一致)

3.2 由补码求其十进制值(快速方法)

  1. 如果符号位是0,则为正数,直接转换。
  2. 如果符号位是1,则为负数。
  3. 对该补码再次求补码(即按位取反再加1),得到的结果就是其绝对值的原码,然后加上负号。

示例: 求补码 1111 0100 的十进制值 1. 符号位是1,所以是负数。 2. 对 1111 0100 求补码: - 按位取反: 0000 1011 - 加1: 0000 1100 3. 0000 1100 = 12 4. 所以原值是 -12

3.3 补码的加法运算

规则: 直接按二进制相加,包括符号位。忽略最高位的进位。

示例1: 7 + (-5) - 7的补码: 0000 0111 - -5的补码: 1111 1011 - 相加: ``` 0000 0111 + 1111 1011


1 0000 0010 `` - **忽略溢出的进位**,得到0000 0010` = 2 ✅

示例2: 5 + (-3) - 5的补码: 0000 0101 - -3的补码: 1111 1101 - 相加: ``` 0000 0101 + 1111 1101


1 0000 0010 `` - 忽略进位,得到0000 0010` = 2 ✅

3.4 补码的减法运算

规则: A - B = A + (-B)。即,将减数B求负(求其补码),然后与被减数A相加。

示例: 8 - 3 - 8的补码: 0000 1000 - 3的补码: 0000 0011 - -3的补码: 1111 1101 - 计算 8 + (-3): ``` 0000 1000 + 1111 1101


1 0000 0101 `` - 忽略进位,得到0000 0101` = 5 ✅


4. 特殊情况

4.1 溢出 (Overflow)

当两个正数相加得到负数,或两个负数相加得到正数时,发生了溢出。结果是不正确的。 - 判断方法: 只有当两个加数的符号位相同,且结果的符号位与它们不同时,才发生溢出。 - 示例: 120 + 10 (8位) - 120补码: 0111 1000 - 10补码: 0000 1010 - 相加: 0111 1000 + 0000 1010 = 1000 0010 (结果是 -126,显然是错误的,因为130 > 127) - 判断: 两个正数(符号0)相加,结果符号位为1(负数),溢出发生。

4.2 最小负数(没有原码和反码)

在8位补码中,范围是 -128 到 +127。 - -128的补码是 1000 0000。 - 特殊点: -128 这个数没有原码和反码,因为8位原码/反码的范围是 -127 到 +127。 - 对 1000 0000 求补码(按位取反得 0111 1111,加1得 1000 0000),还是它自己。这解释了为什么它是 -128。

4.3 零的表示

  • 原码/反码: 有 +0 和 -0 两种表示,这在进行相等判断时很麻烦。
  • 补码: 唯一的零,表示为 0000 0000。这是补码的一大优势。

总结

特性 原码 反码 补码
正数表示 与二进制相同 与原码相同 与原码相同
负数表示 符号位1+绝对值 正数原码按位取反 反码 + 1
零的表示 +0 和 -0 +0 和 -0 唯一的0
表示范围(8位) -127 ~ +127 -127 ~ +127 -128 ~ +127
减法操作 复杂 较复杂 转换为加法
硬件实现 复杂 较复杂 简单高效

结论: 由于补码解决了零的歧义、统一了加减法运算、扩大了表示范围,并且硬件实现简单,因此现代计算机一律使用补码来表示和存储有符号整数。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码