计算机中的数制和编码
一、无符号数 Σ(i=-m 到 n-1) NX = ki Xi
1.无符号的表示方法:
十进制:用D表示十进制数,任意一个十进制可以表示为ND =Σ(i=-m 到 n-1) Di 10i
例:138.5=1×10²+3×10¹+8×10º×+5×10-1
二进制:用H表示十进制数,任意一个二进制可以表示为NB= Σ(i=-m 到 n-1) Hi 2i
例如:1101.11B=1×2³+1×2²+0×2¹+1×2º+1×2-1+1×2-2=13.75(D)
十六进制:用H表示十六进制数,任意一个十六进制进制可以表示为NH =Σ(i=-m 到 n-1)Hi 16i
A ~ F代表(10~15)
例如:
0E5AD.BFH=0×164+14×16³+5×162+10×16¹+13×16º+11×16-1+15×16-2=58797.7461(D)
2.数制间的互相转换
(1)将X进制转换成十进制,按位权展开,即就是上面各个例题。
(2)将十进制转换成X进制,整数部分:除位权取余,小数部分:乘位权取整。
例如:十进制转换成二进制:13.75(D)=1101.11=1×2³+1×2²+0×2¹+1×2º+1×2-1+1×2-2
- 整数部分:
13/2=6 余1
6/2=3 余0
3/2=1 余1
1/2=0 余1 从下往上读为:1101 - 小数部分:
0.75×2=1.50 取整1
0.5×2=1.0 取整1 从上往下读为:11
十进制转换成其他进制类似。
3.二进制数的运算
- 算术运算:
(1)加:0+0=0 0+1=1 1+0=0 1+1=0(进位)
(2)减:0-0=0 1-1=0 1-0=0 0-1=1(借位)
(3)乘:0×0=0 0×1=0 1×0=0 1×1=1
(4)除:乘法的逆运算。 - 逻辑运算:
(1)“与”运算(AND):0∧0=0 0∧1=0 1∧0=0 1∧1=1
(2)“或”运算(OR):0∨0=0 0∨1=1 1∨0=1 1∨1=1
(3)“非”运算(NOT):0非=1 1非=0
(4)“异或”运算(XOR):0⊕0=0 0⊕1=1 1⊕0=1 1⊕1=0
二、带符号数的表示及运算:
1.机器数与真值:
对于一个字节型二进制来说D7位为符号位,D6~D0为数值位。符号位“0”代表正,“1”代表负。
通常把一个数及其符号位在机器中的一组二进制数表示形式称为“机器数”。机器数所表示的值成为该机器数的“真值”。
机器数有不同的表示方法,常用的有原码表示法,反码表示法和补码表示法。
2.机器数的表示方法:
- 原码:范围为-(2n-1-1)~ +(2n-1-1)8位二进制原码的范围为:-127 ~ +127,16位二进制原码范围为:-32767~+32767;0的原码有两种表示方法:00000000表示+0,10000000表示-0。
- 反码:8位二进制反码的范围为:-127 ~ +127,16位二进制反码范围为:-32767~+32767;0的反码有两种表示方法:00000000表示+0,11111111表示-0。
正数的反码是它本身。
例如:
(机器字长n=8时)
[+0]反=[+0]原=00000000B [+127]反=[-127]原=01111111B
(机器字长n=16时)
[+0]反=[+0]原=0000000000000000B [+127]反=[-127]原=0000000001111111B
负数的反码是在原码的基础上保留符号位,数值位按位取反。
例如:
(机器字长n=8时)
[-0]原=10000000B [-127]原=11111111B
[-0]反=11111111B [-127]反=10000000B
- 补码:8位二进制补码的范围为:-128 ~ +127,16位二进制补码范围为:-32768~+32767;
正数的补码是它本身;负数的补码是在原码的基础上保留符号位,数值位按位取反,末位加1。或者反码的基础上加1.
例如:
(机器字长n=8时)
[+8]补=[+8]反=[+8]原=00001000B [+127]补=[+127]反=[-127]原=01111111B
(机器字长n=16时)
[+8]补=[+8]反=[+8]原=0000000000001000B
[+127]补=[+127]反=[-127]原=0000000001111111B
负数的补码是在原码的基础上保留符号位,数值位按位取反,末位加1。或者反码的基础上加1
例如:
(机器字长n=8时)
[-8]原=10001000B [-127]原=11111111B
[-8]反=11110111B [-127]反=10000000B
[-8]补=11111000B [-127]补=10000001B
求补码的另一种直接看方式:在原码的基础上从最低位往高位看,第一个1和符号位之间的数值位取反,其余不变。例如:[-8]的原码为10001000,从最低位往高位看,第一个1和符号位的1之间取反后面数值位不变为11111000。
下表为8位2进制数的原码、反码、补码
二进制数 | 无符号十进制数 | 带符号数 | ||
---|---|---|---|---|
原码 | 反码 | 补码 | ||
0000 0000 | 0 | +0 | +0 | +0 |
0000 0001 | 1 | +1 | +1 | +1 |
0000 0002 | 2 | +2 | +2 | +2 |
... | ... | ... | ... | ... |
0111 1110 | 126 | +126 | +126 | +126 |
0111 1111 | 127 | +127 | +127 | +127 |
1000 0000 | 128 | -0 | -127 | -128 |
1000 0001 | 129 | -1 | -126 | -127 |
... | ... | ... | ... | ... |
1111 1101 | 253 | -125 | -2 | -3 |
1111 1110 | 254 | -126 | -1 | -2 |
1111 1111 | 255 | -127 | -0 | -1 |
3.真值与及其数的转换:
1.原码转为真值:按位权展开
2.反码转为真值:反码取反得到原码,再按位权展开
3.补码转为真值:补码求补得到原码,再按位权展开
4.补码的加减运算:
[X]补+[Y]补=[X+Y]补
加法举例:
二进制(补码)加法 十进制加法
0100 0010 [+66]补 +66
(+) 0011 0011 [+51]补 (+) +51
———————————— ——————
0111 0101 [+117]补 +117
由于
[+66]补+[+51]补=[(+66)+(+51)]补=01110101B
结果为正,因此
[(+66)+(+51)]原=(+66)+(+51)]补=01110101B
二进制(补码)加法 十进制加法
0100 0010 [+66]补 +66
(+) 1100 1101 [-51]补 (+) -51
———————————— ——————
[1] 0000 1111 [+15]补 +15
↑
自动丢失
由于
[+66]补+[-51]补=[(+66)+(-51)]补=00001111B
结果为正,因此
[(+66)+(-51)]原=(+66)+(-51)]补=00001111B
可以看出,不论被加数、加数是正数还是负数,只要直接用它们的补码直接相加,当结果不超出补码所表示的范围时,计算结果便是正确的补码形式。但当计算结果超出补码表示范围时,结果就不正确了,这种情况称为溢出。有关补码运算时溢出的概念及溢出的判断方法下面介绍。
当最高位向更高位的进位由于机器字长的限制而自动丢失时,不会影响计算结果的正确性。
减法举例:
二进制(补码)加法 十进制加法
0100 0010 [+66]补 +66
(+) 1100 1101 [-51]补 (+) -51
———————————— ——————
[1] 0000 1111 [+15]补 +15
↑
自动丢失
可以看出, 无论被减数、减数是正数还是负数,上述补码减法的规则都是正确的。同样,由最高位向更高位的进位会自动丢失而不影响运算结果的正确性。
计算机中带符号数用补码表示时有如下优点:
①可以将减法运算变为加法运算,因此可使用同一个运算器实现加法和减法运算,简化了电路。
②无符号数和带符号数的加法运算可以用同一个加法器 实现,结果都是正确的。
5.溢出及判断方法:
1.进位溢出
所谓进位,是指运算结果的最高位向更高位的进位,用来判断无符号数运算结果是否超出了计算机所能表示的最大无符号数的范围。
溢出是指带符号数的补码运年溢出,用来判断带符号数补码运算结果是否超出了补码所能表示的范围。例如,字长为n位的带符号数,它能表示的补码范围为-2n-1 ~ +2n-1-1如果运算结果超出此范围,就叫补码溢出,简称溢出。
2.溢出的判断方法
判断溢出的方法很多,常见的有:①通过参加运算的两个数的符号及运算结果的符号进行判断。②单符号位法。 该方法通过符号位和数值部分最高位的进位状态来判断结果是否溢出。③双符号位法,又称为变形补码法。它是通过运算结果的两个符号位的状态来判断结果是否溢出。
上述三种方法中,第①种方法仅适用于手工运算时对结果是否溢出的判断,其他两种方法在计算机中都有使用。下面通过具体例子对第②种方法做简要介绍。
若符号位进位状态用CF来表示,当符号位向前有进位时,CF=1, 否则,CF=0;数值部分最高位的进位状态用DF来表示, 当该位向前有进位时,DF=1, 否则,DF=0。 单符号位法就是通过该两位进位状态的异或结果来判断是否溢出的。
例题:
无符号数 有符号数
0100 0100 66 [+68]补
(+) 0100 1000 (+) 72 [+72]补
—————————— —————— ——————
1000 1100 140 [+140]补
↑↑ DF=1(数值最高位向符号位进位1)
↑↑ CF=0(符号位向前无进位)
①若为无符号数,由于CF=0,说明结果未超出8位无符号数所能表达的数值范围(0~255),计算结果0001100B为无符号数,其真值为140,计算结果正确。
②若为带符号数补码, 由于CF⊕DF=1,结果溢出;这里也可通过参加运算的两个数的符号及运算结果的符号进行判断,由于两操作数均为正数,而结果却为负数,因而结果溢出;+68和+72两数补码之和应为+140的补码,而8位带符号数补码所能表达的数值范围为-128~+127,结果超出该范围,因此结果是错误的。
同理:
①若为无符号数,由于CF=1,说明结果超出8位无符号数所能表达的数值范(0~255)。两操作数11101110B和11001000B对应的无符号数分别为238和200,两数之和应为438>255,因此,计算结果是错误的。
②若为带符号数补码,由于CF⊕DF =0,结果未溢出。两操作数11101110B和11001000B分别为-18和-56的补码,其结果应为-74的补码形式,而计算结果10110110B 正是-74的补码,因此结果正确。
变补:
首先,变补是一种运算,不是一种码制,比如说要求(x±y)补,则有两种情况。当“+”运算的时候,直接使用[x]补+[y]补;当“-”运算的时候,虽然是[x]补-[y]补,但是要转换成“+”运算,即[x]补+[-y]补,这样的操作是先将 y 取负,再得到[-y]补,进行运算。另一种方法就是对[y]补实行变补,得到[-y]补
在大多数计算机中,通常只设置加法器而不设置减法器,减法运算将转换为加法运算来实现。原码运算时,用|X|+[|Y|]变补来代替|X|-|Y|。
变补的具体操作:不论[y]补是正还是负,连其符号位一起变反,末位加 1。
例如:[+51]补=0011 0011B
0011 0011连同符号位取反1100 1100再加1为1100 1101,即为[-51]补=1100 1101B