浮点数运算
假定有两个浮点数 X=Mx 2Ex , Y=My 2Ey
(1)加减运算
实现X±Y运算,需要如下五步:
11 对阶 *** 作,即比较两个浮点数的阶码值的大小求△E=Ex-Ey。当其不等于零时,首先应使两个数取相同的阶码值。其实现方法是,将原来阶码小的数的尾数右移|△E|位,其阶码值加上|△E|,即每右移一次尾数要使阶码加1,则该浮点数的值不变(但精度变差了)。尾数右移时,对原码形式的尾数,符号位不参加移位,尾数高位补0;对补码形式的尾数,符号位要参加右移并使自己保持不变。为减少误差,可用另外的线路,保留右移过程中丢掉的一到几位的高位值,供以后舍入 *** 作使用。
12 实现尾数的加(减)运算,对两个完成对阶后的浮点数执行求和(差) *** 作。
13 规格化处理,若得到的结果不满足规格化规则,就必须把它变成规格化的数,规格化处理规则如下:
当结果尾数的两个符号位的值不同时,表明尾数运算结果溢出。此时应 使结果尾数右移一位,并使阶码的值加1,这被称为向右规格化,简称右规。
当尾数的运算结果不溢出,但最高数值位与符号位同值,表明不满足规格化规则,此时应重复地使尾数左移、阶减减1,直到出现在最高数值位上的值与符号位的值不同为止,这是向左规格化的 *** 作,简称左规。
14 舍入 *** 作。在执行对阶或右规 *** 作时,会使尾数低位上的一位或多位的数值被移掉,使数值的精度受到影响,可以把移掉的几个高位的值保存起来供舍入使用。舍入的总的原则是要有舍有入,而且尽量使舍和入的机会均等,以防止误差积累。常用的办法有"0"舍"1"入法,即移掉的最高位为1时 则在尾数末位加1;为0时则舍去移掉的数值。该方案的最大误差为2-(n+1)。这样做可能又使尾数溢出,此时就要再做一次右规。另一种方法 "置1"法,即右移时,丢掉移出的原低位上的值,并把结果的最低位置成1。该方案同样有使结果尾数变大或变小两种可能。即舍入前尾数最低位已为0,使其变1,对正数而言,其值变大,等于最低位入了个1。若尾数最低位已为1,则再对其置1无实际效用,等于舍掉了丢失的尾数低位值。
15 判结果的正确性,即检查阶码是否溢出。浮点数的溢出是以其阶码溢出表现出来的。在加减运算真正结束前,要检查是否产生了溢出,若阶码正常,加(减)运算正常结束;若阶码下溢,要置运算结果为浮点形式的机器零,若上溢,则置溢出标志。
例15:某浮点数阶码6位(含1位符号位:阶符),补码表示,尾数10位(含1位符号位,数符),补码表示, X=2010B 011011011B, Y=2100B (-010101100B),求 X+Y
解: 由已知条件,Ex=+010B,Mx = 011011011 B,
Ey=+100B,My =-010101100 B
对应补码分别为
[Ex]补=[+010B] 补=[+00010B] 补=000010B
[Mx]补= [+011011011 B]补=[0110110110 B] 补=0, 110110110 B
[Ey]补=[+100B] 补=[+00100B] 补=000100B
[-Ey]补=111100B
[My]补= [-010101100 B]补=[-0101011000 B] 补=1, 010101000 B
浮点表示分别为:
数符 阶码 尾数数值
[X]浮 = 0 000010110110110
[Y]浮 = 1 000100010101000
15_(1)对阶
[△ E]补= [Ex]补+[-Ey]补= 00 00010B + 11 11100B = 11 11110B
△E =-00010B=-2,说明X的阶码小,应使Mx右移两位,Ex加2
所以修正[X]浮 = 0 000100 001101101 10
15_(2)尾数求和
00 001101101 10
+ 11 010101000
11 100010101 10
15_(3)尾数规格化
尾数运算结果的符号位与最高数值位均为1,应执行左规处理,具体为:将尾数左移一位,符号位1位,结果为1000101011, 阶码减1变为000011。
15_(4)尾数移出位的舍入处理
左规已将对阶移出的1位有效1移入,尾数不用做舍入处理。
15_(5)判溢出,写结果
尾数已规格化且阶码符号位为00,没有溢出,最终结果为
[Ex+y]补=000011 Ex+y=+00011B
[Mx+y]补=1000101011 Mx+y=-0111010101B
所以,X+Y = 2+0011B (-0111010101B)
(2)乘法运算
实现XY运算,需要如下三步:
21 尾数相乘(两个定点小数相乘)
22 阶码求和
23 结果左规、舍入
例16:某浮点数阶码3位(含1位符号位:阶符),补码表示,尾数3位(含1位符号位,数符),原码表示, X=210B 01101B, Y=2-01B (-01011B),求 XY
解:由已知条件,Ex=+10B,Mx = 01101 B,
Ey=-01B,My =-01011 B
对应机器数分别为:
[Ex]补=[+10B]补=010B
[Mx]原= [+01101 B]原=0, 1101 B
[Ey]补=[-01B]补=111B
[My]原= [-01011B]原=1, 1011B
机内浮点表示分别为:
数符 阶码 尾数数值
[X]浮 = 0 010 1101
[Y]浮 = 1 111 1011
16_(1)尾数相乘(Mx My)
11 [ | Mx | ]原= [+01101 B]原=0, 1101 B
[|My | ]原= [+01011B]原=0, 1011B
12 高 位 积 乘数/低位积
Y0
00 0000 1 0 1 1
+[ Y0|X| ]补 00 1101
00 1101
右移 00 0110 1 1 0 1
+[ Y0|X| ]补 00 1101
01 0011
右移 00 1001 1 1 1 0
+[ Y0|X| ]补 00 0000
00 1001
右移 00 0100 1 1 1 1
+[ Y0|X| ]补 00 1101
01 0001
右移 00 1000 1 1 1 1
13 [Mx My] 符号=[ Mx ]符号⊕[My]符号=0⊕1=1
14 [Mx My] 原=1,100011110B
16_(2)阶码求和
00 10
+ 11 11
00 01
16_(3)结果左规、舍入
尾数已为规格化形式,由于数值部分职能保存4位,需对小数点后第5位进行0设1入,最终尾数原码为1,1001B
最终运算结果为:1 001 1001
所以,XY = 2+01B (-01001B)
(3)除法运算
实现X/Y运算,需要如下三步:
31 尾数相除(两个定点小数相除)
32 阶码相减
33 结果规格化及舍入
例17:某浮点数阶码3位(含1位符号位:阶符),补码表示,尾数3位(含1位符号位,数符),原码表示, X=210B 00011B, Y=2-01B 01011B,求 X/Y
解:由已知条件,Ex=+10B,Mx = 00011 B,
Ey=-01B,My =-01011 B
对应机器数分别为
[Ex]补=[+10B]补=010B
[Mx]原= [+00011 B]原=0, 0011B
[Ey]补=[-01B]补=111B
[My]原= [-01011B]原=1, 1011B
机内浮点表示分别为:
数符 阶码 尾数数值
[X]浮 = 0 010 0011
[Y]浮 = 1 111 1011
17_(1)尾数相除(Mx/ My)
11 [ | Mx | ]原= [+000110000 B]原=0, 00110000 B
[|My | ]原= [+01011B]原=0, 1011B
[-|My | ]补= 1, 0101B
12 被除数高位/余数 被除数低位/商
00 0011 00000
+[-|My |]补 11 0101
11 1100 00000
左移 11 1000 00000
+[ |My |]补 00 1011
00 0011 00001
左移 00 0110 00010
+[-|My |]补 11 0101
11 1011 00010
左移 11 0110 00100
+[|My |]补 00 1011
00 0001 00101
左移 00 0010 01010
+[-|My |]补 11 0101
11 0111 01010
+[|My |]补 00 1011
00 0010
13 [Mx /My] 商符号=[ Mx ]符号⊕[My]符号=0⊕0=0
14 [Mx / My] 商原=0,1010B
17_(2)阶码相减
[-Ey]补=[+01B]补=001B
00 10
+ 00 01
00 11
17_(3)结果规格化、舍入
尾数已为规格化形式,余数过小,结果也不必舍入,
最终运算结果为:0 011 1010
所以,XY = 2+11B (+01010B)求给定数值的补码表示分以下两种情况:
(1)正数的补码
与原码相同。
例1+9的补码是00001001。(备注:这个+9的补码说的是用8位的2进制来表示补码的,补码表示方式很多,还有16位2进制补码表示形式,以及32位2进制补码表示形式等。)
(2)负数的补码
负数的补码是对其原码逐位取反,但符号位除外;然后整个数加1。
同一个数字在不同的补码表示形式里头,是不同的。比方说-15的补码,在8位2进制里头是11110001,然而在16位2进制补码表示的情况下,就成了1111111111110001。在这篇补码概述里头涉及的补码转换默认了把一个数转换成8位2进制的补码形式,每一种补码表示形式都只能表示有限的数字。
例2求-7的补码。
因为给定数是负数,则符号位为“1”。
后七位:-7的原码(10000111)→按位取反(11111000)(负数符号位不变)→加1(11111001)
所以-7的补码是11111001。
已知一个数的补码,求原码的 *** 作分两种情况:
(1)如果补码的符号位为“0”,表示是一个正数,其原码就是补码。
(2)如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。
再举一个例子:求-64的补码
+64:01000000
11000000
例3已知一个补码为11111001,则原码是10000111(-7)。
因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”。
其余七位1111001取反后为0000110;
再加1,所以是10000111。
在“闲扯原码、反码、补码”文件中,没有提到一个很重要的概念“模”。我在这里稍微介绍一下“模”
的概念:
“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范
围,即都存在一个“模”。例如:
时钟的计量范围是0~11,模=12。
表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。
“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的
余数。任何有模的计量器,均可化减法为加法运算。
例如:
假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:
一种是倒拨4小时,即:10-4=6
另一种是顺拨8小时:10+8=12+6=6
在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。
对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特
性。共同的特点是两者相加等于模。
对于计算机,其概念和方法完全一样。n位计算机,设n=8,
所能表示的最大数是11111111,若再
加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的
模为2^8。
在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以
了。把补数用到计算机对数的处理上,就是补码。
另外两个概念
一的补码(one's
complement)
指的是正数=原码,负数=反码
而二的补码(two's
complement)
指的就是通常所指的补码。
小数补码求法:一种简单的方式,符号位保持1不变,数值位从右边数第一个1及其右边的0保持不变,左边按位取反。
(3)补码的绝对值(称为真值)
例4-65的补码是10111111
若直接将10111111转换成十进制,发现结果并不是-65,而是191。
事实上,在计算机内,如果是一个二进制数,其最左边的位是1,则我们可以判定它为负数,并且是用补码表示。
若要得到一个负二进制数的绝对值(称为真值),只要各位(包括符号位)取反,再加1,就得到真值。
如:二进制值:10111111(-65的补码)
各位取反:01000000
加1:01000001(+65的补码)
编辑本段代数加减运算
1、补码加法
[X+Y]补
=
[X]补
+
[Y]补
例5X=+0110011,Y=-0101001,求[X+Y]补
[X]补=00110011
[Y]补=11010111
[X+Y]补
=
[X]补
+
[Y]补
=
00110011+11010111=00001010
注:因为计算机中运算器的位长是固定的,上述运算中产生的最高位进位将丢掉,所以结果不是
100001010,而是00001010。
2、补码减法
[X-Y]补
=
[X]补
-
[Y]补
=
[X]补
+
[-Y]补
其中[-Y]补称为负补,求负补的方法是:负数的绝对值的原码所有位按位取反;然后整个数加1。
(恢复本来解释。请路人真正理解并实际验证后再修改。以免误导大众。另外,例6不具典型性,新增例7。)
例61+(-1)
[十进制]
1的原码00000001
转换成补码:00000001
-1的原码10000001
转换成补码:11111111
1+(-1)=0
00000001+11111111=00000000
00000000转换成十进制为0
0=0所以运算正确。
例7增-7-(-10)
[十进制]
-7的补码:11111001
-10的补码:11110110
-(-10):按位取反再加1实际上就是其负值的补码,为00001010
-7
-
(-10)=
-7
+
10
=
3
11111001+00001010
=
00000011
转换成十进制为3
3、补码乘法
设被乘数X补=X0X1X2……Xn-1,乘数Y补=Y0Y1Y2……Yn-1,
XY补=X补×Y补,即乘数(被乘数)相乘的补码等于补码的相乘。
编辑本段补码的代数解释
任何一个数都可以表示为-a=2^(n-1)-2^(n-1)-a;
这个假设a为正数,那么-a就是负数。而根据二进制转十进制数的方法,我们可以把a表示为:a=k02^0+k12^1+k22^2+……+k(n-2)2^(n-2),第(n-1)位为符号位不计算在内。
这里k0,k1,k2,k(n-2)是1或者0,而且这里设a的二进制位数为n位,即其模为2^(n-1),而2^(n-1)其二项展开是:1+2^0+2^1+2^2+……+2^(n-2),而式子:-a=2^(n-1)-2^(n-1)-a中,2^(n-1)-a代入a=k02^0+k12^1+k22^2+……+k(n-2)2^(n-2)和2^(n-1)=1+2^0+2^1+2^2+……+2^(n-2)两式,2^(n-1)-a=(1-k(n-2))2^(n-2)+(1-k(n-3))2^(n-3)+……+(1-k2)2^2+(1-k1)2^1+(1-k0)2^0+1,而这步转化正是取反再加1的规则的代数原理所在。因为这里k0,k1,k2,k3……不是0就是1,所以1-k0,1-k1,1-k2的运算就是二进制下的取反,而为什么要加1,追溯起来就是2^(n-1)的二项展开式最后还有一项1的缘故。而-a=2^(n-1)-2^(n-1)-a中,还有-2^(n-1)这项未解释,这项就是补码里首位的1,首位1在转化为十进制时要乘上2^(n-1),这正是n位二进制的模。
不能贴公式,所以看起来很麻烦,如果写成代数式子看起来是很方便的。
注:n位二进制,最高位为符号位,因此表示的数值范围-2^(n-1)
--2^(n-1)
-1,所以模为2^(n-1)。上面提到的8位二进制模为2^8是因为最高位非符号位,表示的数值范围为0--2^8-1。学了原码反码补码,就被这句话误导了:〖带符号数在计算机中,是用补码存储的。〗
这句话,对于整数,还是适用的。
对于小数,还有一种浮点数形式,更为通用。
计算机中的各种代码,内容都是 1 和 0,并没有小数点。
那么,小数的小数点,它在何处呢? 这就需要人为的规定。
所以,存放小数,有定点数、浮点数两种格式。
浮点数实用,但是,结构复杂,一般,都不深入讨论。
定点数虽然简单,但是,表达能力有限,所以,几乎没有人使用。
有些教材,把定点小数作为教学内容,还布置许多的习题!
这都是误导。
特别是,这些教材,都把定点小数,规定为纯小数,不包括整数部分!
那么,运算时,出现整数部分,它该怎么办?
一般来说,小数,应该用浮点数格式来存放,不能用补码表示。
建议题主,不要迷恋补码这些没有用的东西。
若考试出这些题,纯属老师无知。
补码:1101101。
首位 1,既代表负号,也代表数值-16。
再加上其它数值位,即可:
-16 + 8 + 2 + 1 + 025 = -475。
补码:1110101。
首位 1,既代表负号,也代表数值-8。
再加上其它数值位,即可:
-8 + 4 + 2 + 05 + 025 = -1375。
用定点补码表示纯小数,采用8位字长。编码10000000和11111111表示的十进制数分别是多少?用定点补码表示纯小数,采用8位字长,最高位为符号为。编码10000000表示-1。因为:编码0000000的反码是1111111,再加1为:10000000,是1。用定点补码表示纯小数,采用8位字长,最高位为符号为。编码11111111表示-00078125。因为:编码1111111的反码是0000000,再加1为:0000001,是00078125。1、正数的补码表示:
正数的补码 = 原码
负数的补码 = {原码符号位不变} + {数值位按位取反后+1} or
= {原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}
以十进制整数+97和-97为例:
+97原码 = 0110_0001b
+97补码 = 0110_0001b
-97原码 = 1110_0001b
-97补码 = 1001_1111b
2、纯小数的原码:
纯小数的原码如何得到呢?方法有很多,在这里提供一种较为便于笔算的方法。
以064为例,通过查阅可知其原码为01010_0011_1101_0111b。
*** 作方法:
将064 2^n 得到X,其中n为预保留的小数点后位数(即认为n为小数之后的小数不重要),X为乘法结果的整数部分。
此处将n取16,得
X = 41943d = 1010_0011_1101_0111b
即064的二进制表示在左移了16位后为1010_0011_1101_0111b,因此可以认为064d = 01010_0011_1101_0111b 与查询结果一致。
再实验n取12,得
X = 2621d = 1010_0011_1101b 即 064d = 01010_0011_1101b,在忽略12位小数之后的位数情况下,计算结果相同。
3、纯小数的补码:
纯小数的补码遵循的规则是:在得到小数的源码后,小数点前1位表示符号,从最低(右)位起,找到第一个“1”照写,之后“见1写0,见0写1”。
以-064为例,其原码为11010_0011_1101_0111b
则补码为:10101_1100_0010_1001b
当然在硬件语言如verilog中二进制表示时不可能带有小数点(事实上不知道哪里可以带小数点)。
4、一般带小数的补码
一般来说这种情况下先转为整数运算比较方便
-9764为例,经查询其原码为1110_00011010_0011_1101_0111b
笔算过程:
-9764 2^16 = -6398935 = 1110_0001_1010_0011_1101_0111b,其中小数点在右数第16位,与查询结果一致。
则其补码为1001_1110_0101_1100_0010_1001b,在此采用 负数的补码 = {原码符号位不变} + {数值位按位取反后+1} 方法
5、补码得到原码:
方法:符号位不动,幅度值取反+1 or符号位不动,幅度值-1取反
-9764补码 = 1001_1110()0101_1100_0010_1001b
取反 = 1110_0001()1010_0011_1101_0110b
+1 = 1110_0001()1010_0011_1101_0111b 与查询结果一致
6、补码的拓展:
在运算时必要时要对二进制补码进行数位拓展,此时应将符号位向前拓展。
-5补码 = 4'b1011 = 6'b11_1011
ps原码的拓展是将符号位提到最前面,然后在拓展位上部0
-5原码 = 4‘b’1101 = 6'b10_0101,对其求补码得6'b11_1011,与上文一致。
扩展资料:
计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)