C语言--原码、反码、补码转换
一、核心特性实例
正数的原 / 反 / 补码相同
以 8 位整数 + 7 为例:
原码 = 00000111(符号位 0 表示正,数值位 0000111)
反码 = 00000111(符号位不变,数值位无需取反)
补码 = 00000111(与反码相同,无需加 1)无符号数的原 / 反 / 补码相同
无符号 8 位整数 10,没有符号位,直接用数值表示:
原码 = 反码 = 补码 = 00001010(即数值本身)补码的范围更大(以 8 位为例)
- 原码 / 反码范围:-127 ~ +127(共 255 个数值,包含 + 0 和 - 0 两种 0 的表示);
- 补码范围:-128 ~ +127(共 256 个数值,0 仅一种表示,多容纳 - 128)。
例如:8 位补码中,10000000
表示-128
(原码 / 反码无法表示)。
二、转换规则实例
以 8 位负数 -3
为例(原码:10000011
):
原码 → 反码
规则:符号位不变,数值位取反。
原码1 0000011
(符号位 1,数值位 0000011)
反码1 1111100
(数值位 0000011 取反为 1111100)反码 → 补码
规则:反码 + 1。
反码11111100
+ 1 =11111101
(即 - 3 的补码)补码 → 原码
两种方法结果一致:- 方法 1:补码 - 1 → 数值位取反
补码11111101
- 1 =11111100
(反码)→ 数值位取反 →10000011
(原码) - 方法 2:补码取反 + 1
补码11111101
取反为10000010
→ +1 =10000011
(原码)
- 方法 1:补码 - 1 → 数值位取反
说明:
- 补码的设计解决了原码 / 反码中 “0 有两种表示” 的问题,且能统一正负数的加法运算(计算机底层仅支持加法)。
- 负数的补码是核心,需重点掌握 “原码→反码→补码” 的递进转换,以及补码还原为原码的两种等价方法。
三、运算逻辑
编码方式 | 符号位处理 | 运算转化方式 | 缺陷与应用场景 |
原码 | 符号位单独处理,异号运算时需先比较绝对值大小 | 加法:同号直接加,异号用大绝对值减小绝对值;减法:转化为“被减数 + 相反数” | 存在“+0”和“-0”两种表示(00000000和10000000),运算逻辑复杂,仅用于直观表示数值,实际计算中几乎不用 |
反码 | 符号位参与运算,运算产生的进位需循环到最低位(进位循环) | 加法:直接相加;减法:转化为“被减数 + 减数的反码” | 仍存在“-0”,循环进位处理繁琐,仅作为原码到补码的过渡编码,无实际应用 |
补码 | 符号位参与运算,运算产生的进位直接丢弃(无需处理) | 加法:直接相加;减法:转化为“被减数 + 减数的补码”(减数的补码即其相反数的补码) | 无歧义(仅一个0,运算逻辑简单,是计算机中整数存储和运算的实际使用编码 |
计算机中整数存储和运算均使用补码(解决符号和加减统一问题); |
四、计算示例解析
以 “14 + (-21) = -7” 为例(假设为 8 位计算):
- 转换为补码:
- 14 的补码:00001110(正数的补码 = 原码)
- -21 的补码:11101011(原码 10010101→反码 11101010→补码 11101011)
- 补码相加:00001110 + 11101011 = 11111001(进位丢弃后结果)
- 补码转原码:
- 11111001(补码)-1 = 11111000(反码)
- 反码数值位取反(符号位不变)→10000111(原码),即 - 7,与计算结果一致。