Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66328
  • 博文数量: 12
  • 博客积分: 320
  • 博客等级: 二等列兵
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-18 15:20
文章分类

全部博文(12)

文章存档

2014年(2)

2012年(10)

我的朋友

分类: 嵌入式

2012-05-28 23:01:50

一.乘法计算

A=0.1101,B=0.1011
A·B=A·0.1011
    =0.1·A+0.00·A+0.001·A+0001·A
    =0.1·A+0.00·A+0.001·(A+0.1·A)
    =0.1·A+0.01[0·A+0.1·(A+0.1·A)]
    =0.1·{A+0.1[0·A+0.1·(A+0.1·A)]}

   因为0.1=2的-1次方(二进制),所以更换后可以看出:乘法 其实就由加法移位两种运算结合实现。


在上述加法运算时,被乘数只与部分积的高位相加,其低位被移至乘数右移时所空出的高位中。
一个寄存器存放乘积的高位,一个寄存器存放乘积的低位和乘数,另一个寄存器存放被乘数。


二.原码1位乘
   原码1位乘与上面的乘法极为相似,只差在符号位,所以我们可以通过被乘数和乘数的两个符号位进行异或操作,得出结果的符号位,乘积的数值部分由两个数的绝对值进行运算,就是将符号和值分开计算。
   上述例子中,两个真值都为正数,符号位都为0,异或后的结果也是0,乘积数值部分与上面的计算完全一样,这样可以得出最终结果。


三.原码2位乘
   原码二位乘跟原码一位乘一样,符号位和数值部分的运算是分开进行的,但它是用2位的乘数状态来决定新的部分积的形成。

   两位的乘数的状态由“00”-“11”,分别表示0-3,他们都是用部分积增加0-3倍被乘数后再右移两位。
   由于3倍的被乘数无法通过被乘数左移来获得,所以可以通过4-1倍来实现,但是00-11只能表示0-3倍,所以要引入标志位Cj。通过乘数“11”表示的3倍,再加上Cj位置“1”来实现加1倍,可以实现4倍被乘数(加几倍被乘数都是加在部分积上的)。

   但是,4-1倍被乘数|x|中(|x|是绝对值,因为符号位分开运算),有-|x|,所以要采用“[-|x|]补”补码来实现,参与原码两位乘运算的操作数都是绝对值的补码(绝对值是正数,所以原码=补码。因为实际上是加3倍的|x|,所以结果为正,补码结果=原码结果)。

   因为+2倍被乘数,也就是“+[2|x|]补”时,使部分积的绝对值大于2,所以部分积需取3位符号位并以最高位符号位作真正符号位,才能保证正确运算。
   同时,由于原码二位乘中使用两位的乘数和一位Cj位共同实现,当乘数最高两个有效位为“11”时,Cj需置“1”,但是“11”的加3倍操作是分开“部分积-|x|后右移2位”和“新部分积+|x|”两步来实现的(结合下面例子分析)。但在进行第二步Cj位上的“1”的部分积加1倍|x|时,这时乘数没有内容,是无法进行操作的,所以规定,当乘数的位数是偶数时,需在乘数的最高位前面增加两个0,与Cj上的“1”结合为“00 1”状态,以完成+|x|操作,而且Cj位上的加操作后不必进行移位。



   x=0.111111 , y= -0.111001 (n=6为偶数位,运算时,乘数前加“00”)
   乘积符号位:X0异或y0 = 0异或1 = 1 ,结果是负的。
   [-|x|]补=1.000001,|x|=0.111111,2|x|=1.111110(也就是左移1位),|y|=0.111001

   很多人可能不明白,为什么加3倍的|x|是分开“部分积-|x|后右移2位”和Cj位的“新部分积+|x|”两步来实现,其实+3|x|可以由"+2|x|再+|x|"和"+4|x|-|x|"实现,但是+2倍以上的|x|涉及到被乘数|x|的左移再加部分积,特别是+4|x|,可能将会涉及较多的进位,不容易处理。

   但是"+4|x|-|x|"可以换一种方式实现,就是分开“部分积-|x|后右移2位”和Cj位的“新部分积+|x|”两步。Cj位的“新部分积+|x|”是发生在“原部分积-|x|,再右移2位”的基础上,所以Cj的这个“+|x|”等效于原部分积+左移2位的|x|,左移2位的|x|=4|x|,然后这个部分积-|x|,就是+3|x|的效果。
   “部分积-|x|后右移2位”和Cj位的“新部分积+|x|” 与 “+4|x|-|x|,再右移2位”的运算是等效的,结果也是一样的,但是前者的方法(图中的方法)涉及更少的进位,更为简单、可靠。

四.补码乘法

  (1)当乘数为正数时,不管被乘数符号如何,都可按原码乘法的规则进行运算(“加”和“移位”都按照补码规则进行)。
  (2)当乘数为负数时,补码乘法可以按照“先不考虑符号位,当作正数进行原码相乘,再在最后加上[-x]补进行校正”的做法即可(x是被乘数,最后这步称为 校正)。

   虽然可以将乘数和被乘数的位置进行交换,使得情况(2)的运算用情况(1)代替,使得结果无需校正,但是当两数均为负数时必须进行校正(当两数都为负数时,只需在开始时将两数的符号位都先不考虑,按照原码相乘进行,在最后进行“+[-x]补”和“+[-y]补”两步校正,则可得到最终结果)。
   补码乘法中,乘积的符号位是在运算过程中自然形成的,与原码中的“符号位与数值部分分开计算”有着重要的区别。
   (运算中可能出现绝对值大于1的情况,但并不是溢出<>,故部分积和被乘数都取 2位符号位)

阅读(21496) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~