定点小数补码一位乘(校正法)
程序员文章站
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;
}
运行结果: