#4562. 原码、反码和补码
原码、反码和补码
当前没有测试数据。
一、核心概念定义
在计算机中,数值以二进制形式存储,原码、反码、补码 是表示有符号整数的三种编码方式,核心目的是统一加减法运算(将减法转换为加法),这也是GESP等级考试的高频考点。
- 原码:最直观的编码方式,最高位为符号位(0表示正数,1表示负数),其余位为数值的二进制表示。
- 反码:对原码的补充,正数的反码与原码相同,负数的反码是原码符号位不变,其余数值位按位取反。
- 补码:计算机实际存储和运算的编码,正数的补码与原码/反码相同,负数的补码是其反码加1。
1. 原码(直观但有 ±0)
- 正数原码:符号位 0 + 数值位(十进制转 7 位二进制)。 例:+5 原码 = 0000 0101;+127 原码 = 0111 1111。
- 负数原码:符号位 1 + 数值位(绝对值转 7 位二进制)。 例:-5 原码 = 1000 0101;-127 原码 = 1111 1111。
- 0 的原码:+0 原码0000 0000,-0 原码1000 0000(两种表示)。
- 数值范围:-127(1111 1111) ~ +127(0111 1111)。
2. 反码(为补码铺垫,仍有 ±0)
- 正数反码:与原码完全相同。 例:+5 反码 = 0000 0101;+127 反码 = 0111 1111。
- 负数反码:符号位不变,数值位按位取反(0 变 1,1 变 0)。 例:-5 反码 = 原码1000 0101 → 反码1111 1010;-127 反码 = 1000 0000。
- 0 的反码:+0 反码0000 0000,-0 反码1111 1111(两种表示)。
- 数值范围:-127 ~ +127(与原码一致)。
3. 补码(消除 ±0,范围扩展到 -128)
补码是计算机实际存储数值的方式,核心是 “模运算”(8 位二进制模为 2⁸=256),负数补码 = 模 - 绝对值。
- 正数补码:与原码 / 反码完全相同。 例:+5 补码 = 0000 0101;+127 补码 = 0111 1111。
- 负数补码:反码 + 1(或直接计算 256 - 绝对值)。 例:-5 补码 = 反码1111 1010 + 1 = 1111 1011(或 256-5=251 → 二进制1111 1011);-127 补码 = 反码1000 0000 + 1 = 1000 0001。
- 0 的补码:唯一表示0000 0000(+0/-0 补码统一)。
- -128 的补码:8 位补码中特殊值,无原码 / 反码对应,直接规定为1000 0000(256-128=128 → 二进制1000 0000)。
- 数值范围:-128(1000 0000) ~ +127(0111 1111)。
二、核心要点(考点+易错点)
1. 符号位规则(必考)
- 所有编码的最高位均为符号位:
0 = 正数,1 = 负数。 - 以8位二进制为例(GESP常考8位/16位),数值范围:
- 原码/反码:-127 ~ +127(存在+0和-0两种表示)。
- 补码:-128 ~ +127(唯一表示0,无±0歧义)。
2. 转换规则(核心考点)
| 数值类型 | 原码 → 反码 | 反码 → 补码 | 补码 → 原码 |
|---|---|---|---|
| 正数 | 保持不变 | ||
| 负数 | 符号位不变,数值位取反 | 加1 | 先减1,再符号位不变、数值位取反 |
3. 核心对比表(8 位二进制)
| 表示法 | 正数范围 | 负数范围 | 0 的表示 | 核心特点 |
|---|---|---|---|---|
| 原码 | 0~+127 | -127~-0 | +0(00000000)、-0(10000000) | 直观,有 ±0 歧义 |
| 反码 | +0(00000000)、-0(11111111) | 为补码铺垫,仍有 ±0 歧义 | ||
| 补码 | -128~-1 | 唯一 (00000000) | 无 ±0 歧义,计算机实际存储方式 |
4. GESP 高频考点
- 8 位补码的最小值是 -128(而非 -127),对应二进制1000 0000;最大值是 +127(0111 1111)。
- 补码的 0 只有一种表示,是计算机选择补码存储的核心原因。
- 负数补码转十进制:先减 1 取反,再加负号(例:1111 1011 → 减 1=1111 1010 → 取反 =0000 0101 → 十进制 -5)。
- 16 位二进制扩展:原码 / 反码范围 -32767~+32767,补码范围 -32768~+32767(规律:n 位补码范围是 ~ )。
5. 易错点提醒
- ❌ 误区1:负数补码直接对原码取反(漏了“加1”步骤)。
- ❌ 误区2:8位补码中,-128没有原码/反码(仅补码:
1000 0000)。 - ✅ 关键:计算机中所有有符号数的运算都基于补码。
三、经典示例
示例1:8位二进制下,数值-5的编码转换
#include <iostream>
using namespace std;
int main() {
// 以8位二进制为例,计算-5的原码、反码、补码
// 步骤1:5的二进制(正数):0000 0101
// 步骤2:-5的原码:符号位变1 → 1000 0101
cout << "-5的原码:1000 0101" << endl;
// 步骤3:-5的反码:符号位不变,数值位取反 → 1111 1010
cout << "-5的反码:1111 1010" << endl;
// 步骤4:-5的补码:反码加1 → 1111 1011(或256-5=251→二进制1111 1011)
cout << "-5的补码:1111 1011" << endl;
// 验证:补码转原码(1111 1011 -1 = 1111 1010 → 取反数值位=1000 0101)
cout << "补码1111 1011转回原码:1000 0101(即-5)" << endl;
return 0;
}
输出结果:
-5的原码:1000 0101
-5的反码:1111 1010
-5的补码:1111 1011
补码1111 1011转回原码:1000 0101(即-5)
示例2:补码的减法运算
#include <iostream>
using namespace std;
int main() {
// 计算:3 - 2 = 1(计算机中转换为 3 + (-2),用补码运算)
// 3的补码(正数):0000 0011
// -2的补码:原码1000 0010 → 反码1111 1101 → 补码1111 1110(或256-2=254→二进制1111 1110)
// 补码相加:0000 0011 + 1111 1110 = 1 0000 0001(8位截断后取后8位:0000 0001)
cout << "3 - 2 的补码运算过程:" << endl;
cout << "3的补码: 0000 0011" << endl;
cout << "-2的补码: 1111 1110" << endl;
cout << "相加结果:1 0000 0001 → 截断后:0000 0001(即1)" << endl;
return 0;
}
输出结果:
3 - 2 的补码运算过程:
3的补码: 0000 0011
-2的补码: 1111 1110
相加结果:1 0000 0001 → 截断后:0000 0001(即1)
四、关联知识
- 与二进制运算的关系:补码是计算机实现加减法统一的核心,所有
+、-运算最终都转换为补码的加法,这是理解C++中整数运算的基础。 - 与数据类型的关系:C++中
char(1字节)、short(2字节)、int(4字节)的取值范围,本质是由补码的位数决定的(如int占4字节=32位,补码范围: ~ )。 - 与溢出的关系:整数运算溢出(如8位补码中127+1=-128),本质是补码的进位截断导致,这是GESP中“数值溢出”考点的核心原理。
五、总结
- 核心规则:正数的原/反/补码完全相同;负数补码=反码+1(或模-绝对值),反码=原码数值位取反(符号位不变);n位补码范围为 ~ 。
- 考试重点:8位补码的范围(-128~+127)、补码无±0歧义的特性、负数补码与十进制的互转、16位补码的范围扩展规律。
- 易错点:转换负数补码时不要漏“加1”步骤,牢记-128的8位补码是1000 0000且无对应原/反码,计算机中仅存储补码。
相关
在以下作业中: