欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

定点小数补码一位乘(校正法)

程序员文章站 2024-01-31 14:20:16
...

程序:

// 定点小数补码一位乘(校正法)
// 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> &b)
{
	b >>= 1;						
	b[n - 1] = 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> low)
{
	bitset<2 * n + 1> ans(high.to_string().substr(1) + low.to_string());

	if (ans[2 * n])
	{
		ans = ~ans.to_ullong() + 1;
		ans.set(2 * n);	// NOTE
	}

	return ans;
}

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的补码
	bitset<n> C = GetComplement(Y).to_ullong();	// C是0.Y1Y2...Yn(乘数补码的数值位)
	int cd = n;									// cd是计数器

#pragma region 核心算法

	while (cd--)
	{
		if (C[0])
		{
			A = A + B;		// 算术加
		}
		RightMove(A, C);	// A,C联合右移
	}
	if (Y.test(n))
	{
		A = A - B;			// 应是+([-X]补),硬件实现比-([X]补)好,待改进
	}

#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)
{
	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;
}
运行结果:

定点小数补码一位乘(校正法)