二进制乘法器的c++实现
C++ implementation of binary multiplier
我正在尝试一个32位二进制乘法器的c++实现。我只知道一种方法就是
1011 (this is 11 in decimal)
x 1110 (this is 14 in decimal)
======
0000 (this is 1011 x 0)
1011 (this is 1011 x 1, shifted one position to the left)
1011 (this is 1011 x 1, shifted two positions to the left)
1011 (this is 1011 x 1, shifted three positions to the left)
=========
10011010 (this is 154 in decimal).
是否有另一种方法来做到这一点,这是不那么麻烦的编码,因为我必须做更长二进制数的操作?
你可以使用布斯的乘法算法。更多信息请访问维基百科:http://en.wikipedia.org/wiki/Booth%27s_multiplication_algorithm
是的,您可以通过使用循环来完成这一点。假设类型long
为32位,则long*long的结果为64位。
例如,如果你有一个long A
和一个long B
,你想计算a*b
首先,将结果定义为long long result = 0;
。然后检查B的每个位,如果位为1,将A << X
加到结果中。其中X是位的索引。一个循环就可以完成这个。
long long AA = A;// convernt A to AA to avoid overflow
for( int index=0;i<32;++index )
{
if( B & 0x1 )
result += AA;
AA <<= 1;
B >>= 1;
}
我希望我没有弄错,这个想法可以帮助你。
由于整型的隐式乘法是二进制乘法,您可以直接利用它来处理以28, 216或更高的数字,而不是以21。
如果你假设8位数字(乘以 unsigned char
s),下面的24位示例比你问题中发布的4位乘法更简单。
a1 a2 a3 (this is a 3 byte value)
x b1 b2 b3 (this is another 3 byte value)
======
xx xx xx xx (this is a x b3)
xx xx xx xx (this is a x b2, shifted 8 bits to the left)
xx xx xx xx (this is a x b1, shifted 16 bits to the left)
=================
xx xx xx xx xx xx (this is the result).
您可以将上面的"byte"替换为short
或long
,并相应地调整移位。
只要确保将乘数转换为足够大的类型,以便在相乘之前容纳进位
好吧,任意精度和大数的(正确和有效的)实现是麻烦的,对于在生产代码中使用,通常建议使用经过测试的框架(例如,boost, gmp等)。
但是,如果你自己实现它,我不会将数字存储为位序列,而是存储为像unsigned int
这样的机器单词序列,以充分利用硬件ALU功能。因此,每个单词已经代表了一些位,而你的ALU知道如何将它们相乘。
注意,当你用n
位(基数无关)乘以一个数字时,你会得到一个2n
位的数字,例如99 * 99 = 9801(基数10),0xFF * 0xFF = 0xFE01(基数16)。因此,如果std::uintmax_t
是std::uint64_t
在您的系统上,您可以将您的号码存储为std::uint32_t
的序列。当两个数字相乘时,将它们转换成std::uint64_t
并将它们相乘。上面的32位将用于下一个更高数字的乘法运算。(实际上,您也可以直接将std::uintmax_t
变量相乘,但是获得结果的高部分通常有点棘手,并且涉及内联汇编以访问相应的EDXRDX
寄存器。)
a
的所有数字a[i]
,并将每个数字与b
相乘(不要忘记传播进位)。将结果向上移动i
位,并将所有内容添加到最终结果中。
注意,该算法对于基本乘法的数量具有二次复杂度。如果您有(非常非常)大的数字,您还可以切换到更复杂的方法,如Karatsuba甚至FFT和Schönhage-Strassen。但是在这种情况下,我真的建议使用库。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- std::random_device是如何实现的