定点小数补码一位乘(Booth比较法)

程序:

// 定点小数补码一位乘(Booth比较法)
// http://blog.csdn.net/justme0

#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_ullong() + b.to_ullong();
}
bitset<n + 2> operator-(bitset<n + 2> a, bitset<n + 2> b)
{
	return a.to_ullong() - b.to_ullong();
}

bitset<n + 1> GetComplement(bitset<n + 1> a)
{
	if (a[n])
	{
		a = ~a.to_ullong() + 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_ullong() + 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_ullong();
	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;

#pragma region 核心算法

	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
		}
	}

#pragma endregion 核心算法

	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_ullong());	// 用截断高位的方法取绝对值
	const bitset<n> y(Y.to_ullong());
	bitset<2 * n + 1> ans(x.to_ullong() * y.to_ullong());
	ans[2 * n] = X[n] ^ Y[n];			// 最后单独计算符号位
	return ans;
}

int main(int argc, char **argv)
{
	//freopen("cin.txt", "r", stdin);
	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;
}
运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值