是什么

  • 定义:当相同字长的无符号数赋值给有符号数时,内存中的二进制序列(Bit pattern)完全保持不变,仅仅是编译器解读这串二进制位的规则发生了改变。

  • 大白话:数据本身一字未变,变的是“观察它的滤镜”。无符号数滤镜下看都是正数;有符号数滤镜下,只要最高位是 1,就会被解读为负数

记忆口诀

  • 左移 (<<):不分正负与类型,低位无脑补 0;高位被顶替,符号位可能变(算术溢出)。

  • 右移 (>>)

    • 无符号数(逻辑右移):高位一律补 0。

    • 有符号数(算术右移):保持正负,高位补符号位(正补 0,负补 1),符号位永远不变。

  • 乘除等价:左移 1 位等价于 ,右移 1 位等价于

核心内容

1. 第一道关卡:先看最高位(符号位)是 0 还是 1!

拿到任何一个有符号二进制数(补码),第一步永远是看最高位(符号位)

  • 最高位是 0(正数)

    • 根本不需要任何取反加 1 操作!

    • 原码 = 反码 = 补码(三码合一)。

    • 直接按普通的二进制加权求和,算出来的就是正数的十进制真值。

    • (例:0000 0110 最高位为 0,直接按加权算:)

  • 最高位是 1(负数)

    • 这是负数,才需要进行下一步的转换计算!

2. 负数补码转换的两种不同操作(严禁混淆)

只有在最高位是 1 时,才存在以下两种不同的处理场景:

你的目标适用场景符号位怎么处理?数值位怎么处理?最终结果
操作 A:求负数的原码考试要求写出机器数原码符号位保留 1 绝对不动剩下的所有数值位取反加 1得到最高位为 1 的标准原码
操作 B:求真值(绝对值大小)考试要求算十进制是负几连同符号位在内,全部所有位取反加 1得到该负数的正数绝对值,最后手动添个负号直接得出十进制真值
  • 为什么操作 B 可以“连同符号位全部取反加 1”?

    在模 体系中,“全位取反加 1”等价于数学上的求相反数():

    负数的相反数就是正数(绝对值),所以符号位的 1 取反后自然变成了 0。

3. 补码的负权重本质与数值映射

不是最高位变成了单纯的“符号标记”,而是==补码最高位被赋予了 的负权重==:

位位置(以 8 位为例)b7​(最高位)b6​∼b0​
无符号权重
补码(有符号)权重
  • 本质:状态总数(256 个)不变,只是把无符号数 通过最高位负权重平移映射到了负数区间

  • 模平移公式:设 位无符号数值为 ,对应有符号真值为

    • 最高位为 0():

    • 最高位为 1():

例题

例题 1(正数对照:最高位为 0)

  • 题目:8 位补码为 0000 0110,求其原码及十进制真值。

  • 分析:最高位是 0,判定为正数,三码合一,无需取反加 1。

  • 答案

    • 原码:0000 0110

    • 真值:

例题 2(负数计算:8 位 C 语言类型转换)

  • 题目:执行以下代码,求 m 的十进制真值:

C

unsigned char x = 134; // 1000 0110_2
char m = x;
  • 分析:底层位模式为 1000 0110,最高位是 1,判定为负数。

  • 答案

    • 方法一(全位取反加 1 求绝对值)

      ,添负号得

    • 方法二(符号位不动,数值位取反加 1 求原码)

      符号位保留 1,数值位 000 0110 取反加 1 得 111 1010,原码为 1111 1010,真值

    • 方法三(权重代入法)

    • 方法四(模公式)

例题 3(16 位 MIPS 跳转指令实战)

  • 题目:MIPS 指令 bne 机器码低 16 位 OFFSETFFFAH,求其真值及跳转字节偏移。

  • 分析,最高位为 1,是负数;MIPS 寻址需左移 2 位(乘 4)。

  • 答案

    1. 求真值

      • 全位取反加 1

      • 原码验证:符号位保留 1,其余位取反加 1 得原码 ,真值即为

    2. 字节偏移

⚠️ 易错点

Warning

  • 看到补码就去“取反加 1”最高位是 0 的正数绝对不要动! 正数的原码、反码、补码完全一样。

  • 求原码 vs 求绝对值 傻傻分不清

    • 要写出原码符号位的 1 坚决不动,只动后面的数值位。

    • 想算真值几位数连同符号位全部取反加 1 算出绝对值,前面补个负号即可。

  • 混淆位模式与解释规则 → 赋值时内存里的 0/1 绝不会变化,改变的只是编译器的读取滤镜。

  • 最高位数值误区 → 补码最高位不是单纯的符号标示,它承载着 的真实负权重。