本文将介绍计算机中四种编码: 原码,补码,反码,移码的有关知识。
计算机需要处理的信息包括数值信息以及各种符号,文字,图像语言等信息。但计算机内部的硬件只能表示两个状态0和1,计算机只能对二进制的数字信息进行传送、处理。加工和存储,因此,在计算机的内部,各种信息都必须经过数字化编码后才能被传送加工和处理,必须对这些信息进行编码。
各种数值数据在计算机中的表示的形式成为机器数,其特点是采用二进制计数制,数的符号用0、1表示,小数点则隐含表示而不占位置。机器数对应的实际数值称为数的真值。小数点位置固定的数称为定点数,有无符号数和带符号数之分。计算机中的定点数只采用纯整数或者纯小数形式。
无符号数表示正数,在机器数中没有符号位。对于无符号数,若约定小数点的位置在机器数的最低位后,则是纯整数;若约定小数点的位置在机器数的最高位之前,则是纯小数。
对于带符号数,n位机器数的最高位Xs是表示正负的符号位,其余n-1位则表示数值。若约定小数点的位置在机器数的最低数值位之后,则是纯整数,若约定小数点的位置在机器数的最高位之前(符号位之后),则是纯小数。
带符号定点整数格式: Xs Xn-2 - - - X1 X0 .
带符号顶点小数格式: Xs. Xn-2 - - - X1 X0
("."为小数点位置)
1.原码表示
原码(true form)是最容易理解的一种数据编码表示,也称“符号-数值”表示法。
数值X的原码记为[X]原,如果机器字长为n(即采用n个二进制位表示数据),则最高位是符号位,0表示正号,1表示负号,其余n-1位表示数值的绝对值。数值0的原码表示有两种形式(假设n=8):
[+0]原=0 0000000,[-0]原=1 0000000
由于小数点约定的位置不同,计算机中的数据分为定点小数和定点整数,相应由两种形式的原码定义。
定点小数的原码定义如下:
[X]原= X , 0<=X<1
1-X=1+|X| , -1<X<=0
式中X表示真值,[X]原表示真值X的原码。若X为正,则[X]原与X相同;因为X为纯小数,且0<=X<1,所以最高位(符号位)为0,若X为负,则[X]原为1+|X|,即最高位(符号位)为1,数值位为X的绝对值。课间原码体现了数据的绝对值,因此在乘除运算中常采用原码。
定点整数的原码定义如下:
[X]原= X , 0<=X<2n-1
2n-1-X=2n-1+|X| , -2n-1<X<=0
例:若机器字长n=8
[+35]原=(00100011)2
[-35]原=27-(-35)=(10000000)2+(00100011)2=(10100011)2
[+0.8125]原=(0.1101000)2
[-0.8125]原=1-(-0.8125)=(1.0000000)2+(0.1101000)2=(1.1101000)2
由定义可以得出原码的如下性质:
1.原码表示法用最高位表示符号位,符号位为0表示正,1表示负。数值部分就是原来的数值,即绝对值的真值。
2.真值0在原码表示中不唯一。由定义,[+0]原=0 0000000,[-0]原=1 0000000
3.假设机器字长为n,则
·原码表示的定点小数,其表示范围为: -(1-2-(n-1))~+(1-2-(n-1))
·原码表示的定点小数,其表示范围为:-(2n-1-1)~+(2n-1-1)
4.对于定点小数,当X>0时,0<[X]原<1,当X<0时,1<[X]原<2
对于n为定点整数,当X>0时,0<[X]原<2n-1,当X<0时,2n-1<[X]原<2n.
因此,负数的原码大于整数的原码。
5.由真值转换为原码,可将正数的符号位写0,负数符号位写1,数值位照写即可;由原码转换为真值,则将符号位0写成"+",1写成"-",数值位不变即可。
+ <--->0 ,- <---->1
真值X <----------------------------->[X]原
数值位不变
原码的优点:表示简单直观,机器数和真值间的相互转换很容易。用原码实现乘,除运算的规则很简单,可取其绝对值(原码的数值部分)直接运算,并遵循同号相乘除结果符号为正,异号为负的原则,单独处理符号位。
缺点:实现加减运算较为复杂。
2.补码表示
补码概念的引入:
-3 = +9 ( MOD 12 )
一个负数可以表示成一个正数对于一个数M的补数。
补码的定义:
设模为M,一个n为二进制数X的补码的一般定义为:
[X]补= M + X (M为2n)
上式是一个包含正负数在内的统一定义式。
·若X>0,则模作为超出的部分将被舍去,[X]补=X,因而正数的补码就是其本身。
·若X<0,则[X]补=M-|X|,[X]补就是|X|以M为模的补数。
定点小数的补码定义如下:
[X]补= X=[X]原 ,0<=X<1
2+X = 2-|X| ,-1<=X<0 (MOD 2).
定点整数的补码定义如下:
[X]补= X = [X]原 , 0<=X<2n-1
2n+X =2n-|X| , -1<=X<0 (MOD 2)
例: 设机器字长为8位
[-35]补=28+(-35)=(1 0000 0000)2-(0010 0011)2=(1101 1101)2
[-0.8125]补=2+(-0.8125)=(10.0000000)2-(0.1101000)2=(1.0011000)2
·补码的性质:
1.补码的符号位。
当0<=X<1时,[X]补=X,因此有0<=[X]补<1,可见[X]补的形式必然为0.xxxx...x,所以符号位S=0。
当-1<=X<0时,[X]补=2+X,因此有1<=[X]补<2,可见[X]补的形式必然为1.xxxx...x,所以符号位为S=1。
2.补码中0的表示
[0]补=0,0的补码是唯一的,因此X与[X]补一一对应。
3.补码的表示范围
假设字长为n,则用补码表示定点小数,其范围为 -1<=X<=+(1-2-(n-1)),用补码表示定点整数,范围为 -2-(n-1)<=X<=+(2n-1-1).
4.负数的补码值大于整数的补码值。
5.补码与真值、原码之间的相互转换。
当真值X>=0时,
+ <-------> 0
真值X <----------------------------------> [X]补=[X]原
数值位不变
当真值X<0时,假设机器字长为n,由定义得:
[X]补=2+X=1.111111..1 + X + 0.000000..1=1.111111..1-|X| +0.00000...1
n个1 n-1个0 |X|按位取反 末位+1
由此可以得到负数X转换为补码的规则如下:将|X|的真值按位取反,末位+1。
反过来,由定义[X]补=2+X,得 -X=2-[X]补,又因为 -X=|X|,因此有
|X|= -X=2-[X]补=1.1111..1-[X]补+0.00000..1
[X]补按位取反 末位+1
而真值 X=-|X|,由此得出将负数X的补码[X]补转换为真值X的规则如下:将负数的补码转换为真值时,只需将符号位写为负号"-",补码的各位按位取反,末位+1即可。
当真值X<0时,
"-" <------->1
真值X <----------------------------------->[X]补
数值按位取反,末位加1
当真值X<0时,
符号位1不变
[X]原<------------------------------------>[X]补
数值按位取反,末位加一
另一种原码转换为补码的简便方法:数值部分自低位向高位搜索,第一个1以及其右的各位0保持不变,第一个1左边的各位按位取反。
证明:设数值部分为 X X X... X 1 0..00
_ _ _ _
按位取反后为: X X X...X 0 1..11
_ _ _ _
末位+1: X X X...X 1 0..00
·补码的符号位扩展:
在实际应用的过程中,有时需要扩充补码的位数。
1.要将n位纯小数补码变成2n位,只需在末尾添加n个0即可。
这个很好理解,例如[X]补=0.0000001---->0.000000100000000
2.要将整数补码的模扩大 2n 倍,只需将[X]补的符号位向左复制n位即可。
证明: [X1]补=2n+X ---> X=[X1]补-2n;
[X2]补=22n+ X --->[X2]补= 22n+ [X1]补-2n
将X代入
=2n·2n+ [X1]补-2n =(2n-1)·2n + [X1]补
合 并 n-1个1左移n位 加上[x1]补
·补码的算术右移(除2运算)
算术右移就是除2运算,即已知[X]补,求[X/2]补。
符号位不变
结论: [X]补 ---------------------------------->[X/2]补
按位右移一位
证明: 若X>=0
[X]补 = X ----> X/2= [X]补/2,
[X/2]补 =[X]补/2; 即X>=0时补码右移1位
若X<0
[X]补=2n+X --->X=[X]补-2n,--->X/2=[X]补/2-2n-1
[X/2]补= 2n + X/2 = 2n + [X]补/2 - 2n-1 = 2n-1 + [X]补/2.
1左移n-1位 [X]补右移一位
即X<0时[X/2]补为补码右移1位+1<<(n-1)。
得证。
例: [X1]补=0.1101010 则[X1/2]补=0.0110101
[X2]补=1.0100110 则[X2/2]补=1.1010011
·补码的算术左移
算术左移就是乘2运算,与算术右移损失精度不同算术左移可能产生溢出。
末位补0
结论: [X]补 <---------------------------------->[2X]补
各位左移1位
证明: [X]补= 2+X, X=[X]补-2.
2X=2[X]补-4 ,[2X]补=4 + 2X= 4 + 2[X]补-4 =2[X]补
得证。
例: [X1]补=0.0110100 则[2X1]补=0|0.1101000=0.1101000,未溢出。
[X2]补=1.0010110 则[2X2]补=1|0.0101100=0.0101100,溢出,因为乘2后符号变反。
3.反码表示
反码又称1的补码,下面分别给出定点小数和定点整数的反码定义。
设机器字长为n位,定点小数的反码定义如下:
[X]反 = X ,0<=X<1
2-2-(n-1)+X ,-1<X<=0 (MOD(2-2-(n-1)))
式中X表示真值,[X]反表示真值X的反码。
设机器字长为n位,定点整数的反码定义如下:
[X]反 = X ,0<=X<2n-1
2n-1+X ,-2n-1<X<=0 (MOD(2n-1))
例:设机器字长n=8
[+35]反=(00100011)2
[-35]反=(28-1)+(-35)=(11111111)2-(00100011)2=(11011100)2
[+0.8125]反=(0.1101000)2
[-0.8125]反=(2-2-7)+(-0.8125)=(1.1111111)2-(0.1101000)2=(1.0010111)2
·反码有如下性质:
1.正数的反码与原码相同,负数的反码为该负数对应的原码符号位不变,数值位按位取反。因此,在反码表示中,最高位为符号位,0表示正,1表示负,这一点与原码相同。
2.反码中也有两种0的表示,由定义[+0]反=00...0 ,[-0]反=11...1,这使得反码与真值不能一一对应。
3.假设机器字长为n,则
·反码表示的定点小数,范围为 -(1-2-(n-1))~+(1-2-(n-1))
·反码表示的定点整数,范围为 -(2n-1-1)~+(2n-1-1)
4.负数的反码大于正数的反码,这一点与原码类似。
5.反码与原码的转换。
当X>=0时,由定义,真值X=原码=反码
符号位不变
当X<0时 [X]原 <---------------------------->[X]反
数值位按位取反
证明: 只证X<0部分
[X]原 = 2n-1-X
[X]反=2n -1 + X = 2n-1 + 2n-1 -1 -(-X)
和X的原码比较: 符号位不变 按 位 取 反
4.移码表示
计算机中常用移码来表示浮点数的阶码,阶码为整数,因此我们只介绍定点整数的移码表示。若机器字长为n位,则移码的定义如下:
[X]移=2n-1 + X , -2n-1<=X<2n-1
上式中X为真值,[X]移表示真值X的移码,2n-1是一个固定的偏移值。
移码的性质:
1.移码的符号位。
当-2n-1<=X<0时,0<=[X]移<2n-1,即符号位为0.
当0<=X<2n-1时,2n-1<=[X]移<2n,即符号位为1.
因此,移码中用0表示负,用1表示正,这点与原码,补码,反码都不同。
2.移码中0的表示是唯一的。[0]移=000...0
3.移码的表示范围为 -2n-1<=X<2n-1
4.[X]移与X呈线性正比关系。
5.移码与补码的关系:
假设机器字长为n位,由定点整数移码与补码的定义:
[X]移= 2n-1+X , -2n-1<=X<2n-1
[X]补= X , 0<=X<2n-1
2n+X , -2n-1<=X<0
·当X<0时,[X]补=2n-1 + 2n-1+X =[X]移+2n-1,即X<0时,将[X]移的符号改为1即为[X]补,将[X]补的符号改为0即为[X]移。
·当X>=0时,[X]移= 2n-1 + X=2n-1+[X]补,即X<0时,将[X]移的符号改为0即为[X]补,将[X]补的符号改为1即为[X]移。
综合两方面,可得出结论,将即X<0时,将[X]移的符号位取反即得[X]补,反之亦然。
符号位取反
[X]移 <-------------------->[X]补
转载请注明出处http://www.cppblog.com/RyanWang/archive/2010/02/17/107955.html