1 机器数与真值
1.1 机器数
在计算机系统中,所有数值均以二进制形式存储和处理,这些二进制编码被称为机器数。
机器数不仅表示数值的大小,还需承载符号信息(正负号)。为实现符号表示,计算机采用最高位作为符号位的编码规则:
- 符号位为 0:表示正数;
- 符号位为 1:表示负数。
例如,8 位二进制数 0110 0101 中,最高位 0 表明这是一个正数,其余位表示数值部分。这种符号与数值结合的编码方式,是计算机处理有符号数的基础。
1.2 真值
由于机器数包含符号位,其形式值(直接按二进制转换的结果)与真值(实际表示的数值)可能存在差异。以 8 位机器数 1000 0001 为例:
- 形式值:若直接按无符号数计算,该机器数 1000 0001 等于 129;
- 真值:若按有符号数解析,该机器数最高位 1 表示负数,其余位 000 0001 对应数值1,因此真值为 -1。
这种差异源于机器数的编码规则。计算机需通过符号位判断数值的正负,再结合数值位还原真值。例如,负数的真值通常通过补码形式存储,而正数的真值与其形式值一致。
2 原码、反码、补码详解
2.1 原码:符号与数值的直接对应
原码是最直观的编码方式,其表示与机器数真值表示的一样,规则如下:
- 符号位:最高位表示符号,0 为正,1 为负;
- 数值位:其余位直接表示数值的绝对值。
规则细化:
- 正数的原码:符号位为 0,数值位为其二进制表示。
- 示例:+1 的原码为 [0000 0001]。
- 负数的原码:符号位为 1,数值位为其绝对值对应的二进制。
- 示例:-1 的原码为 [1000 0001]。
- 0 的原码:
- +0:符号位为 0,数值位全为 0,即 [0000 0000]。
- -0: 符号位为 1,数值位全为 0,即 [1000 0000]。
特点与问题:
- 直观但低效:
- 原码直接反映了符号与数值的关系,使得人们能够直观地理解其表示的数值。
- 然而,在进行加减法运算时,原码需要额外处理符号位,这增加了硬件实现的复杂性。
- 零的冗余:
- 原码中存在 +0 和 -0 两种表示形式,这导致了逻辑上的歧义。
- 在实际的计算机系统中,这种冗余通常是不必要的,且可能引发一些潜在的问题。
2.2 反码:原码向补码的转换中介
反码是原码的改进形式,主要用于计算补码或反向解析补码。规则如下:
- 正数的反码:与原码相同。
- 示例:+1 的原码为 [0000 0001],反码仍为 [0000 0001]。
- 负数的反码:符号位不变,数值位逐位取反(0→1,1→0)。
- 示例:-1 的原码为 [1000 0001],反码为 [1111 1110]。
- 0 的反码:
- +0:+0 的原码为 [0000 0000],对应的反码为 [0000 0000]。
- -0: -0 的原码为 [1000 0000],对应的反码为 [1111 1111]。
作用与局限性:
- 过渡作用:反码是补码计算的前置步骤。在补码的计算中,通常先求出反码,然后在反码的基础上加 1 即可得到补码。
- 现代计算机中不直接使用:现代计算机中不直接使用反码进行运算。反码仅作为中间表示形式存在,实际的运算(如加法、减法等)仍以补码为核心。
2.3 补码:计算机运算的核心编码
计算机底层以二进制形式存储数据,这是因为二进制系统仅包含 0 和 1 两个状态,非常适合于电子设备的开关状态表示,从而实现数据的稳定存储与处理。然而,直接存储数值的二进制形式在处理有符号数(即正负数)时并不高效,因为需要额外的逻辑来区分正负并处理符号位。
为了统一处理有符号数并简化运算逻辑,计算机采用了补码作为数值的存储形式。补码是一种数值编码方式,它能够将正数和负数统一表示为二进制形式,并且使得加减运算可以像处理无符号数一样简单。规则如下:
- 正数的补码:与原码、反码相同【三码合一】。
- 示例:+1 的原码、反码、补码均为 [0000 0001]。
- 负数的补码:反码基础上末尾加 1。
- 示例:-1 的原码为 [1000 0001],反码为 [1111 1110],补码为 [1111 1111]。
- 0 的补码:0 的补码唯一表示为 [0000 0000]。
- +0 的原码为 [0000 0000],反码为 [0000 0000],对应的补码为 [0000 0000]。
- -0 的原码为 [1000 0000],反码为 [1111 1111],对应的补码为 [0000 0000],最高位的进位被丢弃了。
- 消除了原码和反码中 +0 和 -0 的冗余。
2.4 三码规则要点总结
正数的原码、反码、补码均相同,实现 “三码合一”。
对于负数:
- 原码:以符号位 1 开头,后跟其绝对值对应的二进制数。
- 反码:保持原码符号位不变,其余数据位逐位取反(0→1,1→0)。
- 补码:在反码的基础上末尾加 1。
此外,原码和反码中存在正负 0 的区分,而补码则确保了 0 的唯一表示。
示例对比(以 8 位二进制表示 +1 、-1 、+0、-0):
数值 | 原码 | 反码 | 补码 |
---|---|---|---|
+1 | [0000 0001] | [0000 0001] | [0000 0001] |
-1 | [1000 0001] | [1111 1110] | [1111 1111] |
+0 | [0000 0000] | [0000 0000] | [0000 0000] 唯一 0 |
-0 | [1000 0000] | [1111 1111] |
3 补码中负数全 0 或全 1 的数值表示
在计算机科学中,有符号整数常采用补码表示法。
当整数的二进制表示全为 1 时,如 8 位的 1111 1111、16 位的 1111 1111 1111 1111 或 32 位的 1111 1111 1111 1111 1111 1111 1111 1111,该整数通常表示 -1。这是补码编码规则的直接体现,在计算机系统中极为常见。
而对于负数,当最高位(符号位)为 1,其余位为 0 时,表示的是 -2 的(位数 - 1)次方。具体来说,当最高位为 1,其余位为 0 时,这个数表示的是该位数下能表示的最小负数,即 -2^(n - 1)(n 为二进制位数)。
例如:
- 4 位二进制数 1000,表示 -2^(4 - 1) = -2^3 = -8。
- 8 位二进制数 1000 0000,表示 -2^(8 - 1) = -2^7 = -128。
- 16 位二进制数 1000 0000 0000 0000,表示 -2^(16 - 1) = -2^15 = -32768。
4 计算机采用补码的原因
4.1 补码运算优势
计算机使用补码进行运算的主要原因是为了简化硬件设计和提高计算效率。补码的设计巧妙地解决了原码表示法中存在的问题,使得计算机能够更高效地执行加减法运算。
4.1.1 原码表示法的问题
在原码表示法中,最高位是符号位,0 表示正数,1 表示负数。然而,这种表示方法在进行减法运算时会导致硬件设计复杂,因为需要额外处理符号位。例如,使用原码进行减法运算时,计算机需要判断两个数的符号,然后根据符号执行不同的操作,这增加了硬件的复杂性和运算时间。
4.1.2 补码表示法的优点
补码表示法通过将减法运算转换为加法运算,简化了硬件设计。在补码表示法中,正数的补码与原码相同,负数的补码是其原码取反加 1。这种表示方法使得计算机在执行加减法运算时,只需进行加法操作,无需额外处理符号位,从而提高了计算效率。
例如,计算 2 - 2 的过程:
- 使用原码表示法:2 的原码是 0000 0010,-2 的原码是 1000 0010,直接进行减法运算需要额外处理符号位。
- 使用补码表示法:2 的补码是 0000 0010,-2 的补码是 1111 1110,将减法转换为加法运算,即 2 + (-2) 的补码,结果为 0000 0000,表示 0,计算过程简单且高效。
4.1.3 补码运算的正确性
补码运算的正确性可以通过上述例子验证。使用补码进行运算时,符号位也参与运算,并且可以得到正确的计算结果。这不仅简化了硬件设计,还提高了运算速度和准确性。
4.2 补码存储优势
计算机使用补码来存储数据的主要原因是为了简化硬件设计和提高计算效率,同时也为了能够表示和处理负数。
4.2.1 无符号整数存储
在无符号整数的存储中,所有的二进制位都用于表示数值的大小。例如,4 个二进制位可以表示从 0 到 15 的整数。这种表示方法简单直接,但由于没有符号位,无法表示负数。
4.2.2 有符号整数存储
为了表示负数,计算机使用补码来表示有符号整数。
- 在补码表示法中,最高位是符号位,0 表示正数,1 表示负数。
- 正数的补码与原码相同,负数的补码是其原码取反加 1。
例如,使用 4 个二进制位表示有符号整数时:
- 正数 0 的补码是 0000,表示十进制的 0。
- 正数 1 的补码是 0001,表示十进制的 1。
- 负数 -1 的补码是 1111,表示十进制的 -1。
- 负数 -8 的补码是 1000,表示十进制的 -8。
- 为了理解这一点,我们可以先考虑用 8 位二进制来表示 -8;
- 在 8 位下,-8 的原码是 1000 1000;
- 数值位取反后得到 1111 0111,末尾再加 1 得到补码 1111 1000;
- 由于我们只使用 4 个二进制位来表示,所以取低 4 位,即 1000,这就是 -8 在 4 位二进制下的补码表示。
这种表示方法使得计算机能够在一个固定的位数内表示更大的数值范围,同时也简化了加减法运算的硬件设计。
4.2.3 补码存储的优势
使用补码存储数据的主要优势在于:
- 统一了加减运算:补码表示法将减法运算转换为加法运算,简化了硬件设计。
- 扩大了数值范围:在相同的位数下,补码表示法能够表示更大的数值范围,包括正数和负数。
- 提高了计算效率:由于加减运算的统一,计算机能够更高效地执行运算。
5 原码与补码的快速转换方法
在计算机中,正数的原码、反码与补码均相同,可简称为 “三码合一”。对于负数而言,其原码与补码之间的转换可通过数值位按位取反后加一(同时保持符号位不变)来实现。
5.1 原码到补码的转换
- 保持符号位:负数的原码最高位为 1,表示符号为负。
- 数值位取反:将原码中除符号位外的其余位按位取反。
- 加 1:将取反后的结果加 1,得到的就是该负数的补码。
例如,对于负数 -5,用 8 位二进制表示:
- 原码:1000 0101
- 数值位取反:1111 1010
- 加 1:1111 1011(这就是 -5 的补码)
5.2 补码到原码的转换
- 保持符号位不变:对于负数,补码的最高位(符号位)是 1,这个位在转换过程中保持不变。
- 对数值位取反:将补码中除符号位以外的其余位(即数值位)进行按位取反操作。
- 对取反后的数值位加 1:将上一步得到的取反后的数值位进行加 1 操作。
- 组合符号位和数值位:将保持不变的符号位和经过加 1 操作后的数值位组合起来,得到原码。
以 -5 的补码 1111 1011 为例:
-
保持符号位不变:符号位是 1。
-
对数值位取反:数值位 111 1011 取反得到 000 0100。
-
对取反后的数值位加 1:000 0100 加 1 得到 000 0101。
-
组合符号位和数值位:符号位 1 和数值位 000 0101 组合起来,得到原码 1000 0101。
但是,该方法存在一定限制,即补码必须以其完整的二进制位数来表示,而不能仅采用截取的低位部分。例如,对于 -8(若仅用 4 位二进制表示为 1000)而言,此方法便不再适用,因为截取的低位无法准确反映数值的符号及完整大小信息,从而可能导致转换错误。
对于 -8(若仅用 4 位二进制表示为 1000)而言:
-
保持符号位不变:符号位是 1。
-
对数值位取反:数值位 000 取反得到 111。
-
对取反后的数值位加 1:111 加 1 得到 000,这里产生了进位,但由于只有 4 位,进位被丢弃!!!
-
组合符号位和数值位:组合符号位和数值位得到 1000,在 4 位二进制中,1000 通常表示 -0 的原码,这显然与实际的 -8 不符,说明了当对取反后的数值位执行加 1 操作时,若产生进位且该进位无法被当前位数所容纳,此方法不再适用!!!
6 计算机内部运算过程
在计算机中,减法运算通常通过补码来实现。下面以计算 10 - 12 为例,详细描述使用补码进行计算的过程。
1. 将十进制数转换为二进制原码
- 10 的二进制原码为:0000 1010
- -12 的二进制原码为:1000 1100(这里最高位为符号位,1 表示负数)
2. 求 -12 的补码
- 先求 -12 的反码:将 -12 的原码除符号位外的其他位取反,得到 1111 0011。
- 再求 -12 的补码:在反码的基础上加 1,得到 1111 0100。
3. 进行二进制加法运算
- 将 10 的原码(即补码) 0000 1010 与 -12 的补码 1111 0100 进行二进制加法运算,得到 1111 1110。
4. 将结果转换为十进制数
- 得到的二进制结果 1111 1110 是补码形式,需要先转换为原码。
- 因为最高位为 1,表示结果为负数,求其原码:
- 常规方法:先减 1 得到 1111 1101,再除符号位外取反得到 1000 0010。
- 快速方法:将 1111 1110 数值位 111 1110 取反后再加 1,得到 000 0001 + 1 = 000 0010,然后加上符号位,最终得到 1000 0010。
- 1000 0010 对应的十进制数为 -2。
7 三码快速转换工具
为了加速开发进度,我们可以借助一些工具来实现原码、反码和补码之间的快速转换。以下是两种可行的方法:
7.1 电脑计算器转换
1. 按下电脑键盘上的 Windows 键,打开开始菜单。在搜索框中输入 “计算器”,并打开计算器应用程序。
2. 在计算器界面中,切换至 “程序员” 模式。
3. 在程序员模式下,你可以输入相应的二进制、八进制、十进制或十六进制数据,计算器会自动进行不同进制之间的转换,并直接显示这些数值在补码表示法下的对应值,方便你查看原码、反码(虽然计算器不直接显示反码,但你可以通过补码间接理解)和补码的具体数值。请注意,计算器显示的数据通常是补码形式,因为这是计算机内部存储和运算的主要编码方式。
7.2 在线工具转换
除了电脑自带的计算器程序,你还可以选择使用一些在线的转换工具。这些工具通常提供了更为直观和便捷的操作界面,只需输入需要转换的数值和选择相应的进制,即可快速得到转换结果。
在线原码/反码/补码计算器:https://www.lddgo.net/convert/number-binary-code