资源描述
综合训练项目二 定点运算器设计
目的和规定: 采用BOOTH算法,编程实现二进制数的乘法运算,进而了解计算机中定点运算的过程。
程序算法思想:
在第一次判断被乘数0110中的最低位0以及右边的位(辅助位0),得00;所以只进行移位操作;第二次判断0110中的低两位,得10,所以作减法操作并移位,这个减法操作相称于减去2a的值;第三次判断被乘数的中间两位,得11,于是只作移位操作;第四次判断0110中的最高两位,得01,于是作加法操作和移位,这个加法相称于加上8a的值,由于a的值已经左移了三次
乘积(R0,R1, P)
例如2*(-4)
[2]补=0010, [-4]补=1100,在乘法开始之前,R0和R1中的初始值为0000和1100,R2中的值为0010
0
初始值
0000 1100 0
第一次循环
1:无操作
2:右移1位
0000 0110 0
第二次循环
1b:减0010
1110 0110
2:右移1位
1111 0011 0
第三次循环
1:无操作
2:右移1位
1111 1001 1
第四次循环
1b:加0010
0001 1001
2:右移1位
1000 1100 1
流程图:
yiyi+1=?
开始
01 10
第四次循环?
乘积寄存器右移一位
1b:R0+R2->R0
00,11
1c:R0-R2->R0
1a
N
完毕
Y
程序代码:
#define _CRT_SECURE_NO_WARNINGS // 定点小数补码一位乘
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
const int n = 4; // 数值位位数
// a,b联合右移(算术移位)
void RightMove(bitset<n + 2> &a, bitset<n + 1> &b, bool &eBit)
{
eBit = b[0];
b >>= 1;
b[n] = a[0];
a >>= 1;
a[n + 1] = a[n]; // 算术右移
}
bitset<n + 2> operator+(bitset<n + 2> a, bitset<n + 2> b) // 求a,b的算术和
{
return a.to_ulong() + b.to_ulong(); //to_ulong()函数用无符号整型的形式返回bitset
}
bitset<n + 2> operator-(bitset<n + 2> a, bitset<n + 2> b)
{
return a.to_ulong() - b.to_ulong();
}
bitset<n + 1> GetComplement(bitset<n + 1> a)
{
if (a[n])
{
a = ~a.to_ulong() + 1; //取反加一
a.set(n); // NOTE
}
return a;
}
bitset<2 * n + 1> GetComplement(const bitset<n + 2> high, const bitset<n + 1> low) // low的最低位舍弃,由于它不属于积,而是本来乘数的符号
{
bitset<2 * n + 1> ans(high.to_string().substr(1) + low.to_string().substr(0, 4));
if (ans[2 * n])
{
ans = ~ans.to_ulong() + 1;
ans.set(2 * n); // NOTE
}
return ans;
}
enum Sign{_00, _01, _10, _11};
Sign Test(bool a, bool b)
{
if (!a && !b)
{
return _00;
}
else if (!a && b)
{
return _01;
}
else if (a && !b)
{
return _10;
}
else // if (a && b) // 所有途径都必须返回值
{
return _11;
}
}
bitset<2 * n + 1> ComplementOneMul(const bitset<n + 1> X, const bitset<n + 1> Y)//传进被乘数X和乘数Y(原码表达)
{
bitset<n + 2> A; // A放部分积(最后是积的高位)
bitset<n + 2> tmp = GetComplement(X).to_ulong();
tmp[n + 1] = tmp[n]; // 注意补码最高位的扩展
const bitset<n + 2> B(tmp); // B是X的补码 //无法运用返回值的不同而重载,故引入tmp
bitset<n + 1> C = GetComplement(Y); // C是Y0.Y1Y2...Yn(Y的补码)
int cd = n + 1; // cd是计数器
bool Yn1 = 0;
while (cd--)
{
switch (Test(C[0], Yn1)) // 检测Y(i+1)-Y(i)
{
case _00: case _11:
break;
case _10:
A = A - B;
break;
case _01:
A = A + B;
break;
default:
break;
}
if (cd != 0) // 最后一次不移位
{
RightMove(A, C, Yn1); // A,C联合右移,C的低位移至Yn1
}
}
return GetComplement(A, C);
}
bitset<2 * n + 1> DirectMul(const bitset<n + 1> X, const bitset<n + 1> Y)
{
const bitset<n> x(X.to_ulong()); // 用截断高位的方法取绝对值
const bitset<n> y(Y.to_ulong());
bitset<2 * n + 1> ans(x.to_ulong() * y.to_ulong());
ans[2 * n] = X[n] ^ Y[n]; // 最后单独计算符号位
return ans;
}
int main(int argc, char **argv)
{
string inputStrX;
string inputStrY;
while (cin >> inputStrX >> inputStrY)
{
const bitset<n + 1> X(inputStrX); // X是被乘数
const bitset<n + 1> Y(inputStrY); // Y是乘数
cout << "ComplementOneMul:\t" << X << " * " << Y << " = "
<< ComplementOneMul(X, Y) << endl;
cout << "DirectMul:\t\t" << X << " * " << Y << " = "
<< DirectMul(X, Y) << endl << endl;
}
return 0;
}
输入及运营结果:
展开阅读全文