第二章:数据的表示与计算
2.1 进位计数制
2.1.1 r进制计数法
① 任意进值 --> 十进制:
KnKn-1…K1K0K-1K-2…K-m = Kn * rn + Kn-1 * rn-1 + …+K0 * r0 + … + K-m*r-m
基数:每个数码为所用到的不同符号的个数,r进制的基数为r
例:二进制 101.1 = 1 * 22 + 0 * 21 + 1 * 20 + 1 * 2-1 = 5.5
2.1.2 二进制<->八进制,十六进制
① 二进制<->八进制 (三位一组,每组转换为对应的八进制数)
② 二进制<->十六进制*(四位一组,每组转换成对应的十六进制符号)*
(位数不足时:首尾两头均可补零)
2.1.3 十进制转换成任意进制
方法:除基取余求整数,乘基取整求小数
例:十进制 -> 二进制 (75.3)10 = (1001011.01001)2
2.1.4 各种进制的书写方式
二进制:(10101)2 10101B
八进制:(1652)8 01652
十六进制:(1652)16 1652H 0x1652
十进制:(1652)10 1652D
2.1.5 真值和机器数
真值:符合人类习惯的数
机器数:原码,反码,补码,移码
2.2 BCD码
2.2.1 8421码的映射关系
解释:即四个数字为一组,每一位代表8 4 2 1 四个数,0和1表示是或者否,最后相加即是对应的十进制数
例:(用8421码进行加法)
十进制:5 + 8 13
8421码:0101 + 1000 1101 ----->(+0110) 1 0011(3)
注:8421码在1010-1111无定义
2.2.2 余三码
方法:相当于 8421 码+(0011)2
对应关系:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 |
2.2.1 2421码(改变权值定义)
记忆方式: 0-4 以0开头 5-9 以1开头
2.3 整数的表示和运算
2.3.1 无符号整数的表示和运算
无符号整数:
- 全部二进制位都是数值位,没有符号位,第i位的位权是2i-1
- n bit无符号整数的表示范围是0~2n-1,超出则溢出
- 可以表示的最小的数为全0,可以表示最大的数为全1
无符号整数的运算:
加法运算:从最低为开始,按位相加,并往最高位进位
减法运算:① 被减数不变,减数变为补码 ② 加法运算
2.3.2 带符号整数的表示
-
原码,反码,补码
① 原码表示法:
- 符号位 0/1 对应”正/负“ ,剩余的数值位表示真值的绝对值
- 若机器字长为(n+1)位,带符号整数的原码表示范围为 -(2n-1) ~ 2n-1
- 真值0有两种形式。+0和-0。[+0]原=0.0000000,[-0]原=1.0000000
-
补码的加法运算
从最低位开始,按位相加(符号位参加运算),并往更高位进位
-
补码的减法运算
将补码B转换为-B,在进行补码的加法即可
graph LR
【B】补<-->|全部位按位取反\n末位+1|【-B】补
快速转换方法:从右往左找到第一个1,其左边全部位按位取反,本身不变
-
原反码的特性对比
-
移码
解释:补码的基础上将符号位取反。注意:移码只能用来表示整数
若机器字长n+1位,移码整数的表示范围:-2n~2n-1
[0]移=10000000 注意:真值0只有一种表示形式
-
定点小数
特别注意:位数拓展时,拓展位置不一样。加减法的处理与定点整数一样
2.3.3 带符号整数的运算
2.3.3.1 原码补码的乘法运算
-
原码的乘法
例:设机器字长为n+1=5位(含一位符号位),[x]原=1.1101,[y]原=0.1011,采用原码乘法求x*y。
[分析]:
① 符号位单独处理,符号位=XS ⨁ \bigoplus ⨁ YS
② 数值位取绝对值进行乘法运算
[解]:
先计算 0.1101 * 0.1011 = 0.10001111
符号位 1 ⨁ \bigoplus ⨁ 0 = 1
则结果为:1.10001111
实现方法:先加法再移位,重复n次,后以单独运算的符号位加以修改
Tips:
a. 乘数的符号位不参与运算,可以省略
b. 原码一位乘可以只用单符号位
c.答题时最终结果最好写为原码的机器数
总结:原码一位乘法:(机器字长为n+1,数值部分占n位)
符号位通过异或确定,数值部分通过被乘数和乘数绝对值的n轮加法,移位完成根据当前乘数中参与运算的位确定ACC中加什么,若当前的运算位 = 1,则(ACC)+[|x|]原;若 = 0,则ACC + 0.
每轮加法后加ACC,MQ的内容统一逻辑右移
-
补码的乘法
例:设机器字长为5位(含一位符号位,n=4),x = -0.1101,y=+0.1011。采用booth算法,求x*y.
[分析]:补码一位乘法
- 进行n轮加法,移位,最后再多来一次加法
- 每次加法可以+0,+[x]补,+[-x]补
- 每次移位是“补码的算数右移”
- 符号位参与运算
n轮加法,算术右移,加法规则如下:
辅助位-MQ中最低位 = 1时,(ACC)+ [x]补
辅助位-MQ中最低位 = 0时,(ACC)+ 0
辅助位-MQ中最低位 = -1时,(ACC) + [-x]补
补码的算术右移
符号位不动,数值位右移,正数右移补0,负数右移补1*(符号位是啥就补啥)*
2.3.3.2 原码补码的除法运算
-
原码的除法
a. 手算方法
例:设机器字长为5位(含一位符号位),x=0.1011,y=0.1101。求 x/y
[方法]:忽略小数点,每确定一位商,进行一次减法,得到4位余数,在余数末尾补0,再确定下一位商,确定5位商即可停止(机器字长为5位)
b. 机器计算方法
例:上题中,采用原码恢复余数法求x/y.
[方法]:
① 符号单独处理:符号位=XS ⨁ \bigoplus ⨁ YS
② 实现方法:上商 0 / 1,得到余数,余数末尾补0
具体实现方法流程图:
graph TD A[老余数-余数=新余数]-->B{新余数为负} B-->|No|C[商1] B-->|Yes|D[商0,+除数恢复为老余数] D-->E[余数逻辑右移] E-->A
-
补码的除法
例:设机器字长为5位(含一位符号位,n=4),x=+0.1000,y=-0.1011。采用补码加减交替除法求x/y.
[分析]:· 符号位参与运算 ·被除数/余数、除数采用双符号位
[解]:
[x]补=00.1000 [y]补=11.0101 [-y]补=00.1011
方法:
a. 被除数与除数同号,则被除数减去除数;异号,则被除数加上除数
b. 余数和除数同号,商1,余数左移一位减去除数;异号,商0,余数左移一位加上除数
重复n次
=> [x/y]补=1.0101 ,余 0.0111 * 2-4
2.4 数据的存储与排列
-
大小端模式
例:4字节int:01(最高有效字节MSB) 23 45 67(最低有效字节LSB)H ->19088743D
大端方式:
… 01H 23H 45H 67H … 对应地址: 0800H 0801H 0802H 0803H 小端方式:
… 67H 45H 23H 01H … 对应地址: 0800H 0801H 0802H 0803H 小端方式更便于机器处理
-
边界对齐方式
2.5 浮点数的表示及其规格化
2.5.1 定点数的局限性
定点数可表示的数字范围有限,但我们不能无限制的增加数据长度
2.5.2 浮点数
-
浮点数的表示
Jf J1J2…Jn Sf S1S2…Sn 阶符 阶码的数值部分 数符 尾数的数值部分 阶码:阶符+数值部分,反映数值大小,常用补码或移码表示的定点整数
尾数:数符+数值部分,反映数值精度,常用原码或补码表示的定点小数
-
浮点数的真值
N=rE *M (r表示阶码的底,通常为2,阶码E反映浮点数的表示范围及小数点的实际位置。尾数M的数值部分的位数n反映浮点数的精度)
例:已知a= 0,01;1,1001 b=0,10;0,01001 ,阶码和尾数均用补码表示,求a,b的真值
解:
a: 阶码:0,01 对应真值 +1
尾数:1,1001 对应真值 -0.0111 (由补码求原码,符号位不变,数值位取反后+1)
a的真值=21*(-0.0111)=-0.111
b:阶码:0,10 对应真值 +2
尾数:0,01001 对应真值 +0.01001 (由补码求原码,正数原码反码补码均相同)
b的真值=22*(0.01001)=+1.001
-
浮点数尾数的规格化
如上题中的b数,若有1B的存储空间,存储时会有溢出现象
解决方法(上题情况下):尾数算术左移一位,阶码减一,直到尾数最高位是有效位**(左规)**
左规和右规:
左规:当浮点数运算的结果为非规格时,将尾数算数左移一位,阶码减一
右规:当浮点数运算的结果出现溢出(双符号位为01或10时),将尾数算数右移一位,阶码加一
(右规) 例:a=010;00,1100 b=010;00,1000 求a+b
解: a=22 * 00.1100 b=22 * 00.1000
a + b = 22 * 00.1100 +22 * 00.1000
=22 * (00.1100 + 00.1000)
=22 * 01.0100
=23 * 00.1010
注:采用双符号位,当溢出发生时可以挽救。更高的符号位是正确的符号位
-
规格化浮点数的特点
2.6 IEEE754
2.6.1 移码
补码的基础上将符号位取反。注意:移码只能用于表示整数(偏置值一般取2n-1,此时移码=符号位取反的补码)
移码的定义:移码 = 真值 + 偏置值 8位移码的偏置值=128D=1000 0000B 即2n-1
例:真值&移码
真值:-127 = -111 1111B
移码 = -111 1111 +1000 0000 = 0000 0001
真值:-3 = -11B
移码 = -11 + 1000 0000 =0111 1101
2.6.2 IEEE 754
- 基本格式
mS | E | M |
---|---|---|
数符 | 阶码部分(用移码表示) | 尾数数值位(原码表示),表示尾数 1.M |
- 各种类型的对应位数
阶码 | 数符 | 尾数数值 | 总位数 | 偏置值(16进制) | 偏置值(10进制) | |
---|---|---|---|---|---|---|
float | 1 | 8 | 23 | 32 | 7FH | 127 |
double | 1 | 11 | 52 | 64 | 3FFH | 1023 |
long double | 1 | 15 | 64 | 80 | 3FFH | 16383 |
规格化的短浮点数真值为:(-1)S * 1.M * 2E-127
规格化的长浮点数真值为:(-1)S * 1.M * 2E-1023
- 真值转换为IEEE格式
例:将十进制数-0.75 转换为IEEE 754 的单精度浮点数格式表示。
答:
(-0.75)10 = (-0.11)2 =(-1.1)2 * 2-1
数符 = 1 ;尾数部分 = .1000…(隐含最高位1) ;阶码真值 = -1;单精度浮点型偏移量 = 127D
移码 = -1 +111 1111 =0111 1110(共八位)
得到所求为:1 0111 1110 1000…(补足28位)
- IEEE格式转换为真值
例:IEEE 754的单精度浮点数 C0 A0 00 00H 的值是多少?
答:
C0 A0 00 00H ->1 100 0000 1 010 0000 0000 0000 0000 0000
数符 = 1 => 是个负数
尾数部分:(1.01)2
移码 10000001 若看作无符号数=129D
阶码真值=129 - 127=(2)10
浮点数真值 = (-1.01)2 * 22 = -1.25 * 22 = -5.0
问:IEEE 754单精度浮点型表示的最小绝对值,最大绝对值是什么?
答:
最小:尾数全0,阶码真值最小-126,真值最小(1.0)2 * 2-126
最大:尾数全1,真值最大(1.111…1)2 * 2127
注意:
只有1<=E<=254时,真值=(-1)S * 1.M *2E-127
当阶码E全为0,尾数M不全为0时,表示非规格化小数±(0.xxxxxx)2*2-126,
当阶码E全为0,尾数M全为0时,表示±0;
当阶码E全为1,尾数M全为0时,表示±∞,
当阶码E全为1,尾数M不全为0时,表示非数值“NaN”
2.7 浮点数的运算
2.7.1 浮点数的加减运算
浮点数加减运算步骤: 9.85211*1012 + 9.996007 * 1010
① 对阶:9.85211 * 1012 + 0.0996007 * 1012 (小阶对大阶,可以减少精度损失)
② 尾数加减:9.9517107 * 1012
③ 规格化:加减后若出现 0.0099517 * 1012,需左规,若尾数加减后出现类似99.517107 * 1012时,需右规。
④ 舍入:若规定只保留6位有效数字,则 9.95171 * 1012
⑤ 判溢出:若规定阶码不能超过两位,则运算后阶码超出范围,则溢出
如:9.85211 * 1099 + 9.96007 * 1099 =19.8218 * 1099.规格化并用四舍五入的原则保留6位尾数,得1.98122 * 10100,此时阶码超过两位,发生溢出(注:尾数溢出未必导致整体溢出)
例:已知十进制x = − 5 256 \frac{-5}{256} 256−5,y = 59 1024 \frac{59}{1024} 102459,按机器补码浮点运算规则计算x-y,结果用二进制表示,浮点数格式如下:阶符取两位,阶码取三位,数符取两位,尾数取9位。
答:
x:5D=101B 1 256 \frac{1}{256} 2561=2-8 => x= -101 * 2-8 = -0.101 * 2-5 = -0.101 * 2-101
y:59D=111011B 1 1024 \frac{1}{1024} 10241=2-10 =>y= 111011 * 2-10 = +0.111011 * 2-4 = +0.111011 * 2-100
x:11011,11.011000000
y:11100,00.111011000
① 对阶:x= 11100,11.101100000 x=-0.0101 * 2-100
② -y=11100,11.00101000 (由y -> -y,尾数全取反之后+1)
x-y = 11100,10.110001000
③ 规格化:11100,10.110001000 -> 11101,11.011000100 (右规) (注:右规时补0 or 1看符号位最高位,与之相同)
④ 舍入:无舍入
⑤ 判溢出:常阶码,无溢出*(阶码符号位相同,无溢出)*,结果真值为:2-3 * (-0.1001111)2
2.7.2 强制转换中的精度损失问题
- 基于 32 位机器的讨论:
- char(8bit) --> int(16bit) --> long(32bit) --> double(64bit)
- float --> double
范围,精度从小到大,转换过程中没有精度损失
- 32位机 (常考)
int 表示整数,范围 -231 ~ 231-1,有效数字32位
float 表示整数及小数,范围 ±(2-126 ~ 2127 * (2 - 2-23)),有效数字23+1=24位,
int --> float :有可能损失精度
float --> int :可能溢出及损失精度