Program:
[Cpp]
// Fixed-point decimal complement one-digit multiplication (Booth comparison)
// Http://blog.csdn.net/justme0
# Define _ CRT_SECURE_NO_WARNINGS
# Include <iostream>
# Include <bitset>
# Include <string>
Using namespace std;
Const int n = 4; // number of digits
// A, B Union right shift (arithmetic shift)
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]; // right shift of arithmetic
}
Bitset <n + 2> operator + (bitset <n + 2> a, bitset <n + 2> B) // evaluate the arithmetic sum of a and 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>)
{
If (a [n])
{
A = ~ A. to_ullong () + 1;
A. set (n); // NOTE
}
Return;
}
Bitset <2 * n + 1> GetComplement (const bitset <n + 2> high, const bitset <n + 1> low) // discard the bitwise of low, because it is not a product, but a symbol of the original multiplier.
{
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 (&&! B)
{
Return _ 10;
}
Else // if (a & B) // all paths must return values
{
Return _ 11;
}
}
Bitset <2 * n + 1> ComplementOneMul (const bitset <n + 1> X, const bitset <n + 1> Y) // transmits the bitset to the multiplier X and the multiplier Y (original code representation)
{
Bitset <n + 2> A; // A places the partial product (the last is the high point of the product)
Bitset <n + 2> tmp = GetComplement (X). to_ullong ();
Tmp [n + 1] = tmp [n]; // pay attention to the extension of the maximum bit of the complement code
Const bitset <n + 2> B (tmp); // B is the complement code of X. // different return values cannot be used to overload the data. Therefore, tmp is introduced.
Bitset <n + 1> C = GetComplement (Y); // C is Y0.Y1Y2... Yn (Y's complement)
Int cd = n + 1; // cd is the counter
Bool Yn1 = 0;
# Pragma region Core Algorithm
While (cd --)
{
Switch (Test (C [0], Yn1) // detect 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) // do not shift the last time
{
RightMove (A, C, Yn1); // A, C union right shift, C Low move to Yn1
}
}
# Pragma endregion Core Algorithm
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 (); // return the absolute value by truncating the high value.
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]; // calculate the symbol bit separately.
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 is the Multiplier
Const bitset <n + 1> Y (inputStrY); // Y is the multiplier.
Cout <"ComplementOneMul: \ t" <X <"*" <Y <"="
<ComplementOneMul (X, Y) <endl;
Cout <"DirectMul: \ t" <X <"*" <Y <"="
<DirectMul (X, Y) <endl;
}
Return 0;
}
Running result: