Java学习之原反补码

原码、反码、补码是计算机中表示​​有符号整数​​的三种编码方式,核心目的是解决​​减法运算​​转化为加法运算的问题(从而简化CPU设计)。下面从​​定义、转换、运算、优缺点和应用​​五个方面清晰讲解:


​一、定义与用途​

  1. ​原码 (Sign-Magnitude)​

    • ​规则​​:最高位为符号位(01负),其余位表示数值的绝对值。
    • ​示例​​:
      • +50 0000101 (8位表示,下同)
      • -51 0000101
    • ​问题​​:0有两种表示(+0=00000000, -0=10000000),且加减运算复杂(需判断符号)。
  2. ​反码 (Ones' Complement)​

    • ​规则​​:
      • 正数:与原码相同。
      • 负数:符号位不变,​​数值位按位取反​​。
    • ​示例​​:
      • -5 → 原码 1 0000101 → 反码 1 1111010
    • ​问题​​:0仍有两种表示(+0=00000000, -0=11111111),加法需修正。
  3. ​补码 (Two's Complement)​​ ✅ ​​计算机真实使用的方式​

    • ​规则​​:
      • 正数:与原码相同。
      • 负数:​​反码 + 1​​(符号位不变,数值位取反后加1)。
    • ​关键特性​​:
      • ​统一 0 的表示​​: 0 只有 00000000
      • ​减法变加法​​:A - B = A + (-B的补码)
    • ​示例​​:
      • -5 → 原码 10000101 → 反码 11111010 → ​​补码 11111011

​二、转换方法(以8位为例)​

数值原码反码补码
+70 00001110 00001110 0000111
-71 00001111 11110001 1111001
+00 00000000 00000000 0000000
-01 00000001 1111111​无​​(被 -128 占用)
-128​无原码/反码​​无​1 0000000

🔍 ​​补码的特殊值​​:

  • 最小负数:-128(8位补码为 10000000,无原码/反码)。
  • 范围:-128+127n位补码范围:[-2^{n-1}, 2^{n-1}-1])。

​三、补码的运算(核心!)​

​1. 加法:直接运算,丢弃进位​
  • 例1:5 + 3 = 8

      00000101  (+5)
    + 00000011  (+3)
    ------------
      00001000  (+8) ✅
  • 例2:7 - 5 = 7 + (-5)

      00000111  (+7)
    + 11111011  (-5的补码)
    ------------
     (1)00000010 → 丢弃进位 → `00000010` (+2) ✅
​2. 减法:转化为加其补码​
  • A - B = A + (-B的补码)
  • 例:-3 - 2 = (-3) + (-2)
      -3的补码 = 11111101
      -2的补码 = 11111110
      11111101
    + 11111110
    ------------
      (1)11111011 → 丢弃进位 → `11111011`(即 -5 的补码)✅
​3. 溢出判断
  • ​规则​​:若​​两个正数相加得负数​​或​​两个负数相加得正数​​,则溢出(结果错误)。
  • ​硬件实现​​:检查最高位的进位 C_n 和次高位的进位 C_{n-1}
    • 溢出标志:V = C_n ⊕ C_{n-1}(异或:不同为1)。

​四、为什么计算机用补码?​

  1. ​统一加减法​​:CPU只需设计加法器即可完成加减法。
  2. ​消除 0 的歧义​​:0 唯一表示为 00...0
  3. ​扩大表示范围​​:可表示最小负数(如8位补码的 -128)。
  4. ​简化运算逻辑​​:无需额外电路处理符号位。

​五、快速计算技巧(应试)​

  1. ​求负数补码​​:

    • 从右向左,保留第一个 1 之前的位不变,之后取反。
    • 例:求 -20 的补码(8位):
      20原码:00010100
      保留最右侧的1及其右边的0:→ _ _ _ 1 0 0
      左侧按位取反:1110 → 11101100 ✅
  2. ​补码转十进制​​:

    • 若符号位为 1,先减 1 再按位取反,加负号。
    • 例:11100011 → 减1:11100010 → 取反:10011101 = -29

​六、考研典型题型(需掌握)​

  1. 计算给定数值的原码、反码、补码(含负数)。
  2. 补码加减运算及溢出判断(结合状态寄存器)。
  3. 结合IEEE 754浮点数(符号位独立处理)。
  4. 设计ALU运算电路(如加法器、溢出标志生成逻辑)。

建议动手计算下面几组值:
-12 的原、反、补码 → ② 18 + (-15) 的补码加法 → ③ -100 在16位补码下的表示。

补充:仅做了解即可,在很多小伙伴学习补码的时候会好奇,为什么这样就可以把减法转换成加法,在这里我们仅做简单介绍,因为后面确实涉及到一些数论的知识,也没有必要从头介绍。

我们知道计算机世界中整数的有范围的(如8位数范围是0~255或-128~127),它遵循的是“模运算”,模运算的定义是:

在一个模 M 系统中,一个数 A 等价于 A + K×M(K 为任意整数)

在生活中我们还有接触更多的模运算,比如钟表:15点 ≡ 3点 mod 12(因为 15 - 12 = 3)。

重要的是负数可以等价表示,在模 M 系统中,负数 -A 可表示为:
-A ≡ M - A mod M

(模 256 的8位系统):
-5 ≡ 256 - 5 = 251 mod 256
因此 7 - 5 = 2 等价于 7 + 251 = 258 ≡ 258 - 256 = 2 mod 256 
(计算机中 251 正是 -5 的补码形式:11111011)

​​补码中的负数 -A 本质上是它在模 2^n 系统中的正数等价表示(即 2^n - |A|)!​

所以补码的根本设计是:负数 = 模 - 绝对值​

那又有同学可能要问了,为什么是取反加一就获得补码了呢?

这取反加一的过程其实就是做了上面那个公式:负数 = 模 - 绝对值​,这个摸得值是很好确定的,就是它的上限2^n,后面的绝对值用原码即可,但由于2^n是要溢出的,所以为了适应计算机硬件,我们用(2^n-1)-|A|+1,这个式子的2^n-1)-|A|这部分是做取反,后面那个加一就是取反再加一中的加一,可能又有小伙伴要问了,前面那部分真的那么巧吗,就是二进制取反,还真的那么巧妙,二进制运算的逻辑中确实暗含了这一条规律,不信的小伙伴们可以自己找几个例子尝试一下,去更深刻的体会一下那巧妙的运算过程,或许你会明白它为什么是这样,至此我们找到了补码为什么这样可以获得补码的原因,那计算机又是怎么把减法变成加法的呢,到这里其实已经很简单了,很普通的带入转换

A - B = A + (2^n - B) ≡ A - B mod 2^n(丢弃进位即模运算)。

 那么为什么要如此费劲的研究补码呢?为什么还需要把减法转换成加法呢?是不是还有什么数学原因啊,其实没有,这样做的原因就是为了节省成本,计算机中加法器的成本是低于减法器的,前面那些如此专业,但它的原因却又如此朴实无华,不禁叫人莞尔一笑。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值