布斯乘法以及带符号数的运算

正在准备考研复习,今天在看袁春风老师的计算机系统基础的时候讲到了布斯算法,于是去了解了一下,百度百科中的布斯算法部分还是讲得挺清楚的。下面是我的一些理解,如有错误欢迎指出。

乘法理解

对于最熟悉的十进制乘法很最基本的运算原理就是一个乘数乘以另一个乘数的个位、十位、百位···数字然后求和。比如== 123 × 456 = 123 × 6 + 123 × 5 × 10 + 123 × 4 × 1 0 2 123\times456 = 123\times6 +123\times5\times10+123\times4\times10^2 123×456=123×6+123×5×10+123×4×102==。放到二进制来看其实它也是这样的,多位数的乘法就是一个乘数乘上另一个乘数的各位求和。那么:
1101 × 1110 = 1101 × 1 × 2 3 + 1101 × 1 × 2 2 + 1101 × 1 × 2 1 + 1101 × 0 × 2 0 1101 \times 1110 = 1101\times1\times2^3+1101\times1\times2^2+1101\times1\times2^1+1101\times0\times2^0 1101×1110=1101×1×23+1101×1×22+1101×1×21+1101×0×20

布斯算法及原理

###原理

已经知道两个二进制数的乘法的实质是上面式子中那样了,假设例举的两个数11011110是无符号数,那么作乘法按照下面的式子来:

这里也体现了各位相乘最后求和的思想。按照上面直接来乘可以看到是要计算三位非0位与乘数的积然后求和,如果说一个乘数的非零位特别多1111111111110,那么运算次数就会更多。而布斯算法很好地解决了这个问题。既然加法会乘这么多次那么用减法就好了。随遇上面的1110可以写成10000-10那么只用乘两次再作减就可以得到结果了,所以这就是布斯算法的原理。通过把求和转换成求差简化运算的次数。

具体算法

算法的基本思想是在乘数的末位添加一个"0",乘数中出现连续的"0"和连续的"1"处不进行任何运算;出现"10"时,作减法;出现"01"时作加法。每次只做一位乘法,因而每一步都右移一位。(来自于《计算机系统基础》)

依然以11011110为例(依然为无符号数),被乘数是1101,乘数是1110,我们知道:
1101 × 1110 = 1101 × 1 × 2 3 + 1101 × 1 × 2 2 + 1101 × 1 × 2 1 + 1101 × 0 × 2 0 = 1101 × ( 10000 − 10 ) 1101 \times 1110 = 1101\times1\times2^3+1101\times1\times2^2+1101\times1\times2^1+1101\times0\times2^0=1101\times(10000-10) 1101×1110=1101×1×23+1101×1×22+1101×1×21+1101×0×20=1101×(1000010)
上面的过程就体现了布斯算法的简化。由上面观察1110 -> 01110 -> (10000 - 10),把这个减法式子统一到一个位串里可以写成100(-1)0。上面的减法是为了简化运算,选什么数来作减可以把原来为1的位简化成0呢?明显是高位比11...10...0还高一位的100...00...0减去高位与11...10...0末位1同位的00...10...0序列而01就标示出了一段连续1的开头,而10也标示出了一段连续1的结尾,只是开头的地方是加,而结尾的地方是减去(不知道说清楚没有),对于连续的1在转化过后明显都变成了0所以这些位就不用理睬。

下面实际地计算一下这两个无符号数11011110,结果和中间结果取8位:

带符号数的计算

无符号数按照常规的方法可作如下计算(依然沿用前面的例子):

得到的答案是正确的,但是当11011110是带符号数的时候,这个答案就不对。难道用常规方法就不能进行带符号数的运算吗。当时在看这部分的时候,书上有一句话“对于带符号整数乘法,大多数处理器中会使用专门的补码乘法器来进行运算,一位补码乘法称为布斯乘法”,所以那个时候在还不太了解布斯乘法,所以误以为规算法无法进行带符号数的运算。其实后来发现,常规算法也是可以计算的,但是结果为什么不对,原因在于:以上两个数为例,进行乘法时中间数其实是乘数和被乘数被扩展成8位后进行各位相乘再截断为8位得到的,所以还是先看成无符号数把位填充满得到的是如下:

而之前算不对原因并非在于是否使用了布斯乘法,而是进行扩展的时候依然按照无符号数的方式进行了0扩展,得到的结果自然不对。

现在把上面的数看成符号数处理,1101 = -3, 1110 = -2,所以正确计算后的结果应该是6

00000110 = 6计算正确。但是这样的方式计算真的好长,因为非0位太多而要进行7次累加,换成布斯算法:

更加简单了,所以实际运算的时候使用的是补码乘法器运用布斯算法专门对带符号数进行运算。

布斯算法在乘法器中的应用

现在有两个带符号数a = -2b = -3,他们在乘法器中的运算如下:

ab补码的长度和为8位,又因为被乘数的末尾也可能是连续1的结尾,所以添加一个附加位0以能够作出10标志的识别。所以首先设一个P,长度为4 + 4 + 1 = 9,还有AS,初始值如下:

每一次都读取P的末两位来判断现在是进行加操作还是减操作,加减操作过后每次还需要把P向右移,此处是算数右移。通过上面的描述其实能对应到之前讲的算法。P10时作减,前面说过作减可以通过加负数补码解决,也就是加上S等同于作减法。P01时作加,也就直接用PA就行。分错开的初始值使得被乘数b与乘数a,不会被交叠而影响到对被除数中各位数的读取,而多次运算移位的过程其实就是手写运算时各位做乘,得到中间值然后累加的过程:

### 定点数运算的实现方法 定点数是一种用于表示数值的数据类型,在计算机硬件中广泛应用于嵌入式系统、信号处理等领域。其核心思想是通过固定的小数点位置来简化浮点数的复杂性和提高计算效率。 #### 1. **定点数的概念** 定点数分为两种形式:纯整数(小数点位于最低有效位之后)和带有固定小数部分的形式。对于后者,假设一个小数点的位置被人为设定,则可以通过缩放因子 \( S \) 来定义该定点数的实际值: \[ V_{\text{real}} = V_{\text{fixed-point}} / S \] 其中 \( S \) 是固定的倍率常量[^1]。 #### 2. **定点数乘法原理** 在定点数乘法中,通常会涉及两个主要步骤:**原始数据扩展** 和 **结果调整**。以下是具体说明: - 假设两个 Q 格式的定点数分别为 \( A.Qm \) 和 \( B.Qn \),它们各自具有 m 和 n 的分数位长度。 - 当这两个数相乘时,得到的新结果将是 \( (Q(m+n)) \)[^3]。 这意味着最终的结果会有更多的分数位数量等于两者之和。为了适应目标系统的存储能力或者精度需求,可能还需要执行后续的截断或舍入操作。 #### 3. **布斯(Booth)算法的应用** 当涉及到补码编码下的有符号数乘法时,可以利用 Booth 算法减少所需的加/减次数从而优化性能。此技术特别适合于硬件电路设计以及某些类型的处理器指令集架构支持下高效完成此类任务。 例如,在一个简单的例子中展示如何应用 Booth 编码来进行两数间的快速乘积求解过程如下所示: ```assembly ; TI C5000 DSP Assembly Code Example Using Registers AR2 & AR3 Pointing To Multipliers 'a' And 'b' MPY ACC,*AR2+,*AR3 ; Multiply contents pointed by AR2 and AR3 into accumulator register A. ``` 上述代码片段展示了基于 Texas Instruments TMS320C5x/C6x 数字信号处理器家族的一个典型实例——使用 `MPY` 指令直接调用内部专用单元加速完成一次完整的多精度乘积累加循环迭代的一部分工作流程。 #### 4. **注意事项** 尽管定点运算提供了良好的速度优势,但在实际开发过程中仍需注意几个方面的问题: - 数据溢出风险控制; - 需要合理规划输入参数范围以免超出预期界限造成错误输出; - 对不同平台间移植性考虑不足可能导致兼容性挑战等问题都需要开发者仔细权衡取舍[^2]。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值