程式:
// 定點小數補碼一位乘(校正法)// 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;}
運行結果: