计算机组成原理
二进制计算
进制运算
二进制小数——>十进制:
其实与二进制转换十进制类似,但是权位是从-1开始的
- N = (0.11001) = 1 × 2 − 1 + 1 × 2 − 2 + 1 × 2 − 5 = 25 32 1\times2^{-1}+1\times2^{-2}+1\times2^{-5}=\frac{25}{32} 1×2−1+1×2−2+1×2−5=3225
- N = (0.01011) = 1 × 2 − 2 + 1 × 2 − 4 + 1 × 2 − 5 = 11 32 1\times2^{-2}+1\times2^{-4}+1\times2^{-5}=\frac{11}{32} 1×2−2+1×2−4+1×2−5=3211
十进制小数——>二进制:
若将 25 32 \frac{25}{32} 3225转换为二进制
重复乘以2 | 得积 | 取数 |
---|---|---|
25/32 | 50/32 = 1+9/16 | 1 |
9/16 | 18/16 = 1+1/8 | 1 |
1/8 | 1/4 = 0 + 1/4 | 0 |
1/4 | 1/2 = 0 + 1/2 | 0 |
1/2 | 1 = 1+0 | 1 |
将取出来的数从上到下拼起来便是0.11001。它就是从25/32转换而来的
二进制转十进制
例:1110 1111 —> 1×2的0次方+1×2的1次方+…+1×2的7次方 = 239
十进制转二进制
例:70 —>(64 + 4 + 2)= 1000000 + 100 + 10 = 1000110
7/16的二进制数:
定点数(定点整数 , 定点小数)
例子 : 11010101
定点整数 : 11010101 定点小数 :0.11010101
有符号数和无符号数
原码表示法
- +237 = 0 1110 1101
- -237 = 1 1110 1101
规定符号位位于数值第一位,使用0表示正数、1表示负数,表达简单明了,是人类最容易理解的表示法。
原码表示法的问题
1.当想要用二进制表示0这个整数时,它会有两种情况:00、10,代表+0
、-0
。这显然是不合理的。
2.原码进行运算非常复杂,特别是两个操作数符号不同的时候。有以下步骤:
- 判断两个操作数绝对值大小
- 使用绝对值大的数减去绝对值小的数
- 对于符号为,以绝对值大的为准
原码表示法改进的思路
- 希望找到不同符号操作数更加简单的运算方法
- 希望找到使用正数代替负数的方法
- 使用加法操作代替减法操作,从而消除减法
补码表示法
计算补码
补码的定义: X = { x 2 n > x ≥ 0 2 n + 1 + x 0 > x ≥ − 2 n X= \begin{cases} x & 2^n > x \ge 0 \\ 2^{n+1}+x & 0>x\ge -2^n \end{cases} X={x2n+1+x2n>x≥00>x≥−2n
1.假设n=4,x=13时,计算x的二进制原码和补码
- 原码:x=0,1101 (逗号前面的数字代表符号位)
- 补码:x=0,1101 (逗号前面的数字代表符号位)
2.假设n=4,x=-13时,计算x的二进制原码和补码
- 原码:x=1,1101
- 补码: 2 n + 1 + x = 2 4 + 1 − 13 = 100000 − 1101 = 10011 = 1 , 0011 2^{n+1}+x = 2^{4+1} - 13 = 100000-1101=10011=1,0011 2n+1+x=24+1−13=100000−1101=10011=1,0011
3.假设n=4,x=-7时,计算x的二进制原码和补码
- 原码:x=1,0111
- 补码: 2 n + 1 + x = 2 4 + 1 − 7 = 100000 − 0111 = 11001 = 1 , 1001 2^{n+1}+x = 2^{4+1} - 7 = 100000-0111=11001=1,1001 2n+1+x=24+1−7=100000−0111=11001=1,1001
补码表示法解决的问题
- **解决了:**希望找到使用正数代替负数的方法
- **没解决:**使用加法操作代替减法操作,从而消除减法。想要用加法操作代替减法操作,但是却在计算补码的过程中使用了减法。
反码表示法
反码的目的是找出原码和补码之间的规律,消除转换过程中的减法。
计算反码
反码的定义: X = { x 2 n > x ≥ 0 ( 2 n + 1 − 1 ) + x 0 > x ≥ − 2 n X= \begin{cases} x & 2^n > x \ge 0 \\ (2^{n+1}-1)+x & 0>x\ge -2^n \end{cases} X={x(2n+1−1)+x2n>x≥00>x≥−2n
1.假设n=4,x=-13时,计算x的二进制原码和反码
- 原码:x=1,1101
- 反码: ( 2 n + 1 − 1 ) + x = ( 2 4 + 1 − 1 ) − 13 = 011111 − 1101 = 10010 = 1 , 0010 (2^{n+1}-1)+x = (2^{4+1}-1) - 13 = 011111-1101=10010=1,0010 (2n+1−1)+x=(24+1−1)−13=011111−1101=10010=1,0010
2.假设n=4,x=-7时,计算x的二进制原码和反码
- 原码:x=1,0111
- 反码: ( 2 n + 1 − 1 ) + x = ( 2 4 + 1 − 1 ) − 7 = 011111 − 0111 = 11000 = 1 , 1000 (2^{n+1}-1)+x = (2^{4+1}-1) - 7 = 011111-0111=11000=1,1000 (2n+1−1)+x=(24+1−1)−7=011111−0111=11000=1,1000
所以,可以总结出:
- 负数的反码等于原码除符号位外按位取反
- 正数的反码就是原码
- 负数的补码等于反码+1
小数的二进制补码表示法
二进制小数的补码公式: X = { x 1 > x ≥ 0 2 + x 0 > x ≥ − 1 X= \begin{cases} x & 1 > x \ge 0 \\ 2+x & 0>x\ge -1 \end{cases} X={x2+x1>x≥00>x≥−1
1.假设 x = 9 16 x=\frac{9}{16} x=169,计算x的二进制原码、反码、补码
- 原码:
x=0,0.1001
(逗号前一位为符号位,注意区分逗号和小数点) - 反码:
x=0,0.1001
- 补码:
x=0,0.1001
2.假设 x = − 11 32 x=-\frac{11}{32} x=−3211,计算x的二进制原码、反码、补码
- 原码:
x=1,0.01011
(逗号前一位为符号位,注意区分逗号和小数点) - 反码:
x=1,1.10100
(取反码时要注意,小数点前面的也要取反,但符号位不取反) - 补码:
x=1,1.10101
定点数的表示方法
小数点固定在某个位置的数称之为定点数
纯小数:符号位 .数值位
,小数点在符号位于数值位之间。
纯整数:符号位 数值位.
,小数点位于数值位的末尾
当一个数不是纯整数也不是纯小数时,那么就要==乘以比例因子来满足定点数保存格式==。
浮点数的表示方法
为什么有了定点数表示方法还要用浮点数?
- 计算机处理的数据大多数并不是纯小数或纯整数
- 数据范围很大,定点数难以表达
浮点数的表示格式
公式:$N = S\times r^j $
S:尾数(分正负) r:基数 j:阶码(分正负)
二进制存储方式:
阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位
尾数必须使用纯小数
若想用二进制表示 0.110101 × 2 10 0.110101 \times 2^{10} 0.110101×210和 0.0110101 × 2 11 0.0110101 \times 2^{11} 0.0110101×211,以下是示例:
N | 阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位(8位) | 结果 |
---|---|---|---|---|---|
11.0101= 0.110101 × 2 10 0.110101 \times 2^{10} 0.110101×210 | 0 | 10 | 0 | 11010100 | 010011010100 |
11.0101= 0.0110101 × 2 11 0.0110101 \times 2^{11} 0.0110101×211 | 0 | 11 | 0 | 01101010 | 011001101010 |
当“尾数数值位”有规定位数时,不足位数则在末尾补0。以上示例规定为8位,不够则在末尾补0
浮点数的表示范围
假设阶码数值取m位,尾数数值取n位
$N = S\times r^j $
阶码范围:
- 阶码能够表示的最大值: 2 m − 1 2^m-1 2m−1
- 阶码能够表示的最小值: − ( 2 m − 1 ) -(2^m-1) −(2m−1)
- 阶码表示范围: [ − ( 2 m − 1 ) , 2 m − 1 ] [-(2^m-1),2^m-1] [−(2m−1),2m−1]
尾数范围(尾数必须是纯小数):
- 尾数能够表示的最大值: 1 − 2 − n 1-2^{-n} 1−2−n
- 尾数能够表示的最小值: 2 − n 2^{-n} 2−n
- 尾数表示范围: [ 2 − n , 1 − 2 − n ] [2^{-n},1-2^{-n}] [2−n,1−2−n]
浮点数的范围:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QJivdVUI-1630937130502)(md%E5%9B%BE%E7%89%87/image-20200818201623891.png)]
浮点数的规格化
浮点数的规格化有以下要求:
- 尾数规定使用纯小数
- 尾数最高位必须是1。(最高位其实是小数点后的第一位)
**示例:**11.0101= 0.110101 × 2 10 0.110101\times2^{10} 0.110101×210。正确形式
- 11.0101= 0.0110101 × 2 11 0.0110101\times2^{11} 0.0110101×211。错误,尾数最高位不为1
- 11.0101= 0.00110101 × 2 100 0.00110101\times2^{100} 0.00110101×2100。错误,尾数最高位不为1
- 11.0101= 1.10101 × 2 1 1.10101\times2^{1} 1.10101×21。错误。尾数不是纯小数
**例子1:**设浮点数字长为16位,阶码为5位,尾数为11位,将十进制数13/128
表示为二进制浮点数。
-
原码=反码=补码:
x=0.0001101000
(尾数11位,包括尾数符号位的0)(小数点前面的那个0不算进尾数,那个0的作用是告诉人们尾数是纯小数)
-
浮点数规格化:x= 0.1101000 × 2 − 11 0.1101000\times2^{-11} 0.1101000×2−11
阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位 |
---|---|---|---|
1 | 0011 | 0 | 1101000000 |
阶码数值位不够时,在前面补0。尾数数值位不够时,在末尾补0
**例子2:**设浮点数字长为16位,阶码为5位,尾数为11位,将十进制数-54
表示为二进制浮点数。
- 原码:
x=1,110110
- 浮点数规格化:x=
−
0.110110
×
2
110
-0.110110\times2^{110}
−0.110110×2110。
- 尾数符:
1
- 尾数:
1101100000
(小数点前面的那个0不算进尾数,那个0的作用是告诉人们尾数是纯小数) - 尾数反码:
0010011111
- 尾数补码:
0010100000
- 尾数符:
阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位 |
---|---|---|---|
0 | 0110 | 1 | 0010100000 |
定点数与浮点数的对比
- 当定点数与浮点数位数相同时,浮点数表示的范围更大
- 当浮点数尾数为规格化数时,浮点数的精度更高
- 浮点数运算包含阶码和尾数,浮点数的运算更为复杂
- 浮点数在数的表示范围、精度、溢出处理、编程等方面均优于定点数
- 浮点数在数的运算规则、运算速度、硬件成本方面不如定点数
定点数的加减法运算
定点数的加法
- 整数加法:
A[补]+B[补]=(A+B)[补]
( m o d 2 n + 1 ) (mod2^{n+1}) (mod2n+1) - 小数加法:
A[补]+B[补]=(A+B)[补]
( m o d 2 ) (mod2) (mod2)
数值位与符号位一同运算,并将符号位产生的进位自然丢掉。以上mod的作用其实就是把符号位产生的进位丢掉
**例子1(整数):**A=-110010,B=001101,求A+B
- A[补]=
1,001110
- B[补]=B[原]=
0,001101
A[补]+B[补]=(A+B)[补]=1,011011
- 结果:
A+B=-100101
**例子2(小数):**A=-0.1010010,B=0.0110100,求A+B
- A[补]=
1,1.0101110
(逗号前一位是符号位) - B[补]=B[原]=
0,0.0110100
A[补]+B[补]=(A+B)[补]=1,1.1100010
。本条式子求出来的是A+B的补码,还要转换成为原码才能知道A+B的值。因此通过将补码-1再取反就可以求出原码- A+B的补码-1等于
-1.1100001
,然后再取反就等于-0.0011110
- 结果:
A+B=-0.0011110
例子3(整数):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xipqiyXN-1630937130505)(md%E5%9B%BE%E7%89%87/image-20200819000400067.png)]
**例子4(小数):**A=-10010000,B=-11010000,求A+B
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzh0Jtay-1630937130507)(md%E5%9B%BE%E7%89%87/image-20200819001911165.png)]
在例4里,A是负数、B是负数,但是A+B的结果为什么是整数呢?其实这里发生了溢出。A和B都由一个符号位和八个数值位组成,而八个二进制数的补码能表示的范围其实是[-128,127]
。因为A+B=-144-208=-352
超过了8位二进制补码能表示的范围,所以就产生了溢出,发生了结果异常的现象
判断溢出
双符号位判断法:
- 原本用一个符号位表示,现在用两个符号位表示:
0—>00,1—>11
- 双符号位产生的进位也丢弃
- 计算出的结果的双符号位不同则表示溢出
现在我们使用双符号位来判断例4是否产生溢出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hU0uHtOV-1630937130510)(md%E5%9B%BE%E7%89%87/image-20200819003629423.png)]
现在我们再使用双符号位来判断例3是否产生溢出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ma0fb2A-1630937130512)(md%E5%9B%BE%E7%89%87/image-20200819004155861.png)]
定点数的减法
- 整数减法:
A[补]-B[补]=A+(-B)[补]
( m o d 2 n + 1 ) (mod2^{n+1}) (mod2n+1) - 小数减法:
A[补]-B[补]=A+(-B)[补]
( m o d 2 ) (mod2) (mod2)
-B[补]等于B[补]连同符号位全部取反,末位加1
如:B[补]=1,0010101
,则(-B)[补]=0,1101011
**例子5(整数):**A=11001000,B=-00110100,求A-B
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qenMhZvp-1630937130513)(md%E5%9B%BE%E7%89%87/image-20200819010420564.png)]
浮点数的加减法运算
**步骤:**对阶——尾数求和——尾数规格化——舍入——溢出判断。
**示例:**若x= 0.1101 × 2 01 0.1101\times2^{01} 0.1101×201,y= ( − 0.1010 ) × 2 11 (-0.1010)\times2^{11} (−0.1010)×211。计算x+y
对阶
- 浮点数尾数的运算简单
- 浮点数位数实际小数位与阶码有关
- 阶码按小阶看齐大阶的原则
对阶的目的是使得两个浮点数阶码一致,使得尾数可以直接运算。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sOXXTZDR-1630937130514)(md%E5%9B%BE%E7%89%87/image-20200819234218857.png)]
由于y的阶码大于x的阶码,所以将x的阶码变为11。然后x的尾数就要右移两位,变为001101,由于在该题目中尾数数值位只有四位,所以右移两位后001101的后两位就要舍弃掉,从而变成0011
尾数求和
- 使用补码进行运算
- 减法运算转化为加法运算
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6BX85spo-1630937130516)(md%E5%9B%BE%E7%89%87/image-20200819235210841.png)]
尾数规格化
- 对补码进行规格化需要判断两种情况:S>0和S<0
- S[补]=
00.1xxxxxx(S>0)
- S[补]=
11.0xxxxxx(S<0)
- S[补]=
如果不满足此格式,需要进行左移,同时阶码相应变化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZlZuiovN-1630937130517)(md%E5%9B%BE%E7%89%87/image-20200820000623717.png)]
尾数规格化(右移的情况)
- 一般情况下都是左移
- 双符号位不一致的情况下才需要右移(相当于定点运算的溢出情况)
- 右移,则需要进行舍入操作
舍入
采用0舍1入
的机制(可以理解为二进制的四舍五入)
若S[补]=10.10110111
。
- 双符号位不一致,所以进行右移的操作。
- 右移,移出的是最后的那个1,变成
1.01011011
。由于采用的是双符号位的形式,所以等同于11.01011011
- 根据舍入的原则——
0舍1入
。因此舍去了之后还要+1。所以将11.01011011+1
变成最终结果:11.01011100
- 进行了一次右移操作,阶码要+1
舍入发生溢出的情况:
若S[补]=01.11111111
。
- 双符号位不一致,所以进行右移的操作。
- 右移,移出的是最后的那个1,变成
0.11111111
。由于采用的是双符号位的形式,所以等同于00.11111111
- 根据舍入的原则——
0舍1入
。因此舍去了之后还要+1。所以将00.11111111+1
变成01.00000000
- 由于双符号位还是不一致,所以还要进行右移操作。移出的是最后的那个0,变成
0.10000000
由于采用的是双符号位的形式,所以等同于00.10000000
- 根据舍入的原则——
0舍1入
。舍去的是0,所以不需要+1。最终结果为:00.10000000
- 进行了两次右移操作,阶码要+2
溢出判断
- 定点运算双符号位不一致为溢出
- 浮点运算尾数双符号位不一致不算溢出
如果规格化后,阶码双符号位不一致,则认为是溢出。
例子
若x= 0.11010011 × 2 1101 0.11010011\times2^{1101} 0.11010011×21101,y= 0.11101110 × 2 1100 0.11101110\times2^{1100} 0.11101110×21100,假设阶码6位,尾数8位,计算x+y
-
对阶:
由于x的阶码数值位比y的阶码数值位大,所以y的阶码要与x的阶码相同,因此要+1。并且y的尾数要右移一位。所以得出y= 0.01110111 × 2 1101 0.01110111\times2^{1101} 0.01110111×21101
-
尾数求和:
x尾数=
00.11010011
,y尾数=00.01110111
。将两者相加等于01.01001010
-
规格化(右规):
01.01001010
——>00.10100101
。根据根据舍入的原则——0舍1入
,0舍去。变成00.10100101
-
溢出判断:
阶码双符号位一致,没有溢出 -
结果:
x+y[原]=x+y[补]= 0.10100101 × 2 1110 0.10100101\times2^{1110} 0.10100101×21110
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uuTlJaQ9-1630937130518)(md%E5%9B%BE%E7%89%87/image-20200821010937212.png)]
IEEE 754标准
本处仅解析32位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RoD3j1bT-1630937130519)(md%E5%9B%BE%E7%89%87/image-20200824205254572.png)]
值得注意的是:阶码采用移码表示,尾数采用原码表示
类型 | 数符 | 阶码 | 尾数数值 | 总位数 | 偏置值 |
---|---|---|---|---|---|
短浮点数 | 1 | 8 | 23 | 32 | 127 |
在32位浮点数中,符号位占1位,尾数占23位,阶数占8位。在正常情况下,阶数不包括全零和全一的情况,偏置常数是127,因此阶码的取值范围是[-126,127]。尾数值等于1+尾数23位表示的小数。(尾数部分有个隐含的十进制1)
表示范围
格式 | 最小值 | 最大值 |
---|---|---|
正数 | E=1,M=0:
1.0
×
2
1
−
127
=
2
−
126
1.0\times2^{1-127}=2^{-126}
1.0×21−127=2−126 | E=254,M= 0.11...1 + 1 :
1.11...1
×
2
254
−
127
=
2
127
×
(
2
−
2
−
23
)
1.11...1\times2^{254-127}=2^{127}\times(2-2^{-23})
1.11...1×2254−127=2127×(2−2−23) |
负数 | − ( 2 − 2 − 23 ) × 2 127 -(2-2^{-23})\times2^{127} −(2−2−23)×2127 | − 1.0 × 2 − 126 -1.0\times2^{-126} −1.0×2−126 |
为什么会有 2 127 × ( 2 − 2 − 23 ) 2^{127}\times(2-2^{-23}) 2127×(2−2−23), 2 − 2 − 23 2-2^{-23} 2−2−23代表的是什么意思?
其实尾数最大的时候是0.11...1
,且根据IEEE754标准,尾数最高位还隐藏了一个1,所以尾数此时为1.11...1
。那我们应该怎么表示1.11..1
呢?其实我们可以使用1.11...1 = 2 - 0.00...1
便可以表示出
2
−
2
−
23
2-2^{-23}
2−2−23
转换运算
公式:$N = S\times r^j $
**例子1:**有一个IEEE754标准的单精度浮点数的十六进制表示为0x41390000,求该浮点数的十进制值。
- 转换:先将十六进制41390000转为二进制数:
0100 0001 0011 1001
。后面全为0,所以不用写出来都可以。 - 判断正负:转换后的二进制数第一位为0,所以最后求得的十进制是正数。
- 计算阶码:阶码有8位,也就是符号位后的8位都是代表阶码的移码。
100 0001 0
转换为十进制为130,再减去偏置值130-127=3。所以阶码为3。 - 计算尾数:阶码之后的二进制数便都是尾数,所以有
011 1001
(后面后面全为0,所以不用写出来都可以),那么就有—— 2 − 2 + 2 − 3 + 2 − 4 + 2 − 7 2^{-2}+2^{-3}+2^{-4}+2^{-7} 2−2+2−3+2−4+2−7。由于在IEEE754标准中,尾数最高位还有隐藏的1,所以有—— 1 + 2 − 2 + 2 − 3 + 2 − 4 + 2 − 7 1+2^{-2}+2^{-3}+2^{-4}+2^{-7} 1+2−2+2−3+2−4+2−7。 - 计算结果:根据公式有——
N
=
(
1
+
2
−
2
+
2
−
3
+
2
−
4
+
2
−
7
)
×
2
3
N=(1+2^{-2}+2^{-3}+2^{-4}+2^{-7})\times2^{3}
N=(1+2−2+2−3+2−4+2−7)×23。计算可得
11.5625
.11…1,且根据IEEE754标准,尾数最高位还隐藏了一个1,所以尾数此时为
1.11…1。那我们应该怎么表示
1.11…1呢?其实我们可以使用
1.11…1 = 2 - 0.00…1`便可以表示出
2
−
2
−
23
2-2^{-23}
2−2−23
转换运算
公式:$N = S\times r^j $
**例子1:**有一个IEEE754标准的单精度浮点数的十六进制表示为0x41390000,求该浮点数的十进制值。
- 转换:先将十六进制41390000转为二进制数:
0100 0001 0011 1001
。后面全为0,所以不用写出来都可以。 - 判断正负:转换后的二进制数第一位为0,所以最后求得的十进制是正数。
- 计算阶码:阶码有8位,也就是符号位后的8位都是代表阶码的移码。
100 0001 0
转换为十进制为130,再减去偏置值130-127=3。所以阶码为3。 - 计算尾数:阶码之后的二进制数便都是尾数,所以有
011 1001
(后面后面全为0,所以不用写出来都可以),那么就有—— 2 − 2 + 2 − 3 + 2 − 4 + 2 − 7 2^{-2}+2^{-3}+2^{-4}+2^{-7} 2−2+2−3+2−4+2−7。由于在IEEE754标准中,尾数最高位还有隐藏的1,所以有—— 1 + 2 − 2 + 2 − 3 + 2 − 4 + 2 − 7 1+2^{-2}+2^{-3}+2^{-4}+2^{-7} 1+2−2+2−3+2−4+2−7。 - 计算结果:根据公式有——
N
=
(
1
+
2
−
2
+
2
−
3
+
2
−
4
+
2
−
7
)
×
2
3
N=(1+2^{-2}+2^{-3}+2^{-4}+2^{-7})\times2^{3}
N=(1+2−2+2−3+2−4+2−7)×23。计算可得
11.5625
注:此乃黄敢敢夜观各大网站视频所学即得笔记,如有雷同,请联系我进行删除!阿里嘎多
又注:还没写完笔记哟,同步更新