文章目录
真值与机器数
在日常生活中,通常用正号、负号来分别表示正数(正号可省略)和负数,如+15、-8 等。这种带 “+
” 或 “-
” 符号的数称为真值。真值是机器数所代表的实际值。
在计算机中,通常将数的符号和数值部分一起编码,将数据的符号数字化,通常用“0”表示“正”,用“1”表示“负”。这种把符号“数字化”的数称为机器数。常用的有原码、补码和反码表示法。如 0.101
(这里的逗号“”仅用于区分符号位与数值位)表示 +5
。
机器数的定点表示
根据小数点的位置是否固定,在计算机中有两种数据格式:
-
定点表示(定点数)
-
浮点表示(浮点数)
在现代计算机中,通常用补码整数表示整数,用原码小数表示浮点数的尾数部分,用移码表示浮点数的阶码部分。
定点数是一种在计算机系统中用于表示有理数的方法,它与浮点数不同,没有动态的小数点位置。在定点数表示法中,小数点的位置是固定的,这使得定点数的运算速度通常比浮点数快,但其表示范围和精度受到限制。定点数可以分为无符号定点数和带符号定点数两种类型。
定点表示法用来表示定点小数和定点整数:
-
定点小数:纯小数,约定小数点位置在符号位之后、有效数值部分最高位之前。若数据 X X X 的形式为 X = x 0 . x 1 x 2 … … x n X = x_0.x_1x_2……x_n X=x0.x1x2……xn ( x 0 x_0 x0为符号位, x 1 ∼ x n {x_1}\sim{x_n} x1∼xn是数值的有效部分,也称尾数, x 1 x_1 x1为最高有效位)
-
定点整数:纯整数,约定小数点位置在有效数值部分最低位之后。若数据 X X X 的形式为 X = x 0 x 1 x 2 … … x n X = x_0x_1x_2……x_n X=x0x1x2……xn ( x 0 x_0 x0为符号位, x 1 ∼ x n {x_1}\sim{x_n} x1∼xn是数值是尾数, x n x_n xn为最低有效位)
实际上,在机器内部并没有小数点,只是人为约定了小数点的位置。因此,在定点数的编码和运算中不用考虑对应的定点数是小数还是整数,只需关心它们的符号位和数值位即可。
定点数的编码分为 原码、补码、反码、移码
定点数所能表示的数据范围与下列因素有关:
-
机器字长:字长越长,其表示的数据范围就越大。
-
所采用的机器码:补码和移码所能表示的数据范围,比原码和反码所能表示的数据范围要多一个最小负数。
原码
原码是一种用于表示带符号数的编码方式,它是计算机中最直观的表示正数和负数的方法之一。在原码表示中:
-
最高位(最左边的一位)被称为符号位,用来表示数的正负:0表示正数,1表示负数。
-
其余位则直接表示数值的绝对值, 因此原码表示又称为带符号的绝对值表示
为了阅读方便,以及区分定点整数的原码表示与定点小数的原码表示,规定:
- 在定点整数的原码表示中,符号位与数值位之间用逗号隔开
- 在定点小数的原码表示中,符号位与数值位之间用小数点隔开
-
原码的优点:表示方法简单直观,与真值的转换简单;用原码实现乘除运算比较简便。
-
原码的缺点:真值 0 在原码中有两种不同的表示, [ + 0 ] 原 = 0 , 0000000 [+0]_原=0,0000000 [+0]原=0,0000000 和 [ − 0 ] 原 = 1 , 0000000 [-0]_原=1,0000000 [−0]原=1,0000000,符号位不能直接参与运算,用原码实现加减运算比较复杂。
因此,原码在计算机中目前仅仅用于表示浮点数的尾码
定点整数
若字长为 n+1
,则原码整数的表示范围为
−
(
2
n
−
1
)
≤
x
≤
2
n
−
1
-(2^n-1)≤~x~≤2^n-1
−(2n−1)≤ x ≤2n−1(关于原点对称)
定点小数
真值 0 在原码中有两种表示方法:
补码
补码是一种用于表示带符号数的编码方式。补码的主要优势在于它可以简化加减法运算,并且只有一个零值,避免了原码中存在的 +0
和 -0
的问题。
模与补数
为了方便说明补码,我们先引入模与补数的概念。模(Module)是指一个数值系统中最大可表示数的下一个数。
在计算机中,通常指的是一个数值计量系统的计量范围,记作 mod
或 M
。例如,对于一个 8 位的无符号整数,其范围是 0 到 255,模为 256(即
2
8
2^8
28)。模的概念在补码运算中非常重要,因为它决定了数值的循环性质。
-
只要确定了“模”,就可找到一个与负数等价的正数来代替此负数,该正数就是负数的补数。
-
超过计量范围的数都应该自动舍弃模数,例如 6 + 13 = 19 ≡ 7 ( m o d 12 ) 6 + 13 = 19 \equiv 7 (mod12) 6+13=19≡7(mod12)
例如,某计算机内部有一个 8 位寄存器,从最高位 B 7 B_7 B7 到最低位 B 0 B_0 B0 共 8 个比特。八个比特共有 2 8 2^8 28 个组合,也就是有 2 8 2^8 28 个不同的数值。因此可认为八位寄存器的计量范围为 2 8 2^8 28,即 mod 为 2 8 2^8 28。
若八位寄存器存储无符号定点整数。从最小值 0 到最大值255,当要存储的数值值大于255, B 7 B_7 B7 到 B 0 B_0 B0 会全部归零,并且向更高位 B 8 B_8 B8 产生进位,此时相应的实进制值为256。由于最高位为 B 7 B_7 B7, B 8 B_8 B8 不存在,因此发生了溢出(超出计量范围),会自动舍弃模数(最高位的进位),寄存器中的各位又从比特 0 开始
补数的特点
一个负数可用它的正补数来替代,而这个正补数可以用模数加上负数本身求得。
对于 mod = 12,
-
+ 8 ≡ − 4 +8 \equiv -4 +8≡−4,有 [ − 4 ] 补 = 12 + ( − 4 ) = + 8 [-4]_补 = 12 + (-4) = +8 [−4]补=12+(−4)=+8
-
+ 3 ≡ − 9 +3 \equiv -9 +3≡−9,有 [ − 9 ] 补 = 12 + ( − 9 ) = + 3 [-9]_补 = 12 + (-9) = +3 [−9]补=12+(−9)=+3
一个正数和一个负数互为补数时,它们绝对值之和即为模数。
-
+ 8 ≡ − 4 +8 \equiv -4 +8≡−4,有 ∣ + 8 ∣ + ∣ − 4 ∣ = 12 |+8| + |-4| = 12 ∣+8∣+∣−4∣=12
-
+ 3 ≡ − 9 +3 \equiv -9 +3≡−9,有 ∣ + 3 ∣ + ∣ − 9 ∣ = 12 |+3| + |-9| = 12 ∣+3∣+∣−9∣=12
正数的补数即该正数本身。
借助补数,我们可以将减法运算用加法实现,符号位也可以直接参与运算
补码
将补数的概念应用到计算机内部,便出现了补码这种机器码(机器数)
-
正数的补码:符号位为0,数值位就是它本身,即正数的补码与其原码相同。
-
负数的补码:等于模数加上该负数本身,而模数就是最高位进位的位权值,负数的补码是其反码加1。
补码的优点:
-
加法和减法可以统一为加法运算,符号位可以直接参与运算,不需要额外的符号处理,运算时符号位的进位作为模会被自动舍弃。例如,计算
5 + (-3)
可以直接将 5 的补码和 -3 的补码相加:- 5 的补码:
0 0000101
- -3 的补码:
1 1111101
- 相加结果:
0 0000010
(即2的补码)
- 5 的补码:
-
真值 0 在补码中只有一种表示,这使得补码比原码多表示一个最小负数。
-
补码的加法器设计相对简单,可以同时处理正数和负数的加减法,这在硬件实现中非常高效。
定点整数的补码
8 位原码和补码所对应的真值:
-
正数的补码与其原码相同
-
负数的补码是其反码加1
-
补码比原码多表示一个数, [ 1 , 00000000 ] 补 [1,0000 0000]_补 [1,00000000]补 为
-128
-
若字长为
n+1
,则补码整数的表示范围为 − 2 n − 1 ≤ x ≤ 2 n − 1 − 1 -2^{n-1} ≤ ~ x ~ ≤ 2^{n-1} -1 −2n−1≤ x ≤2n−1−1(比原码多表示“ − 2 n -2^n −2n”)
目前计算机中普遍采用补码表示有符号定点整数,例如 C 语言中 char
、short
、int
、long
型整数都是采用补码进行表示的。
几个特殊数据的补码表示 :
-
[ + 0 ] 补 = [ − 0 ] 补 = 0 , 00..0 [+0]_补=[-0]_补=0,00..0 [+0]补=[−0]补=0,00..0(含符号位共 n+1 个 0),0 的补码表示是唯一的。
-
[ − 1 ] 补 = 2 n + 1 − 1 = 1 , 11..1 [-1]_补=2^n+1-1=1,11..1 [−1]补=2n+1−1=1,11..1(含符号位共 n+1 个 1)。
-
[ 2 n − 1 ] 补 = 0 , 11..1 [2^n-1]_补=0,11..1 [2n−1]补=0,11..1(n个1),即 n+1 位补码能表示的最大整数。
-
[ − 2 n ] 补 = 1 , 00..0 [-2^n]_补=1,00..0 [−2n]补=1,00..0(n个0),即 n+1 位补码能表示的最小整数。
定点小数的补码
现代计算机中多采用 IEEE 754
标准表示浮点数,而其中的定点小数采用原码表示。因此通常不会涉及定点小数的补码表示
反码
反码是一种用于表示带符号数的编码方式,它是补码的一种中间步骤。反码在计算机中目前很少被使用,主要用于从原码转换到补码的中间过渡。
在反码表示中:
-
正数的反码与原码相同
-
负数的反码是其原码的数值位取反(0变1,1变0)。
-
补码可以通过反码末位 +1 得到
反码的特点:
-
存在两个零值:反码中存在
+0
和-0
两种不同的表示方式,这在实际应用中有时会造成混淆。- 正数0的反码:
0 0000000
- 负数0的反码:
1 1111111
- 正数0的反码:
-
加减法运算复杂:由于存在正数和负数的区分,反码下的加减法运算较为复杂,符号位可以参与计算,但最高位(符号位)产生的进位要加到运算结果的低位(循环进位)。
反码的计算
假设我们有一个 8 位的机器,最高位是符号位,剩下 7 位用来表示数值。
-
正数的反码:
- 正数5的原码:
0 0000101
- 正数5的反码:
0 0000101
(与原码相同)
- 正数5的原码:
-
负数的反码:
- 求负数的原码:以 -5 为例,5 的原码是
0 0000101
,所以-5 的 原码 是1 0000101
。 - 求负数的反码:将 -5 的原码每一位取反,得到
1 1111010
。
- 求负数的原码:以 -5 为例,5 的原码是
定点整数的反码
定点小数的反码
移码
移码(也称为偏置表示法或偏移二进制)是一种用于表示带符号数(只用于定点整数的表示)的编码方式,特别适用于浮点数的阶码部分。
-
移码通过将一个数加上一个固定的偏置值(通常为 2 n 2^n 2n,n 为数值位的位数)来实现,这样可以将所有可能的值映射到非负数范围内,从而简化某些运算和比较操作。
-
在数轴上,移码所表示的范围对应于真值在数轴上的范围向轴的正方向移动 2 n 2^n 2n 个单元。
移码的定义
移码的特点
-
只有一个零值:移码中只有一个零值,这与补码类似,避免了
+0
和-0
的问题。 -
简化比较操作:移码的主要优势在于它可以简化比较操作。由于所有的值都被映射到非负数范围内,最小真值的移码为全 0,最大真值的移码为全 1,保持了真值原有的大小顺序,不考虑移码的符号位,看作无符号二进制数,直接使用无符号数的比较方法来进行大小比较。
-
适用于浮点数的阶码:在
IEEE 754
标准中,浮点数的阶码部分通常使用移码表示,以便简化浮点数的运算和比较。 -
一个真值的移码和补码仅差一个符号位,补码和移码仅符号位相反
定点数编码之间的转换
-
原码、补码、反码的符号位相同,正数的机器码相同。
-
原码、反码的表示在数轴上对称,二者都存在+0 和-0 两个 0。
-
补码、移码的表示在数轴上不对称,零的表示唯一,它们比原码、反码多表示一个数。
-
原码很容易判断大小。而负数的补码、反码很难直接判断大小,可采用如下规则快速判断:对于负数,数值位部分越小,其绝对值越大,即负得越多。
原码、反码、补码、移码之间的转换:
-
原码与补码互为补码(补码的补码就是原码)
-
已知真值 X 的补码,求其相反数的补码:全部位按位取反,末位加一