二进制乘法器的c++实现

C++ implementation of binary multiplier

本文关键字:实现 c++ 乘法器 二进制      更新时间:2023-10-16

我正在尝试一个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 chars),下面的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"替换为shortlong,并相应地调整移位。

只要确保将乘数转换为足够大的类型,以便在相乘之前容纳进位

好吧,任意精度和大数的(正确和有效的)实现是麻烦的,对于在生产代码中使用,通常建议使用经过测试的框架(例如,boost, gmp等)。

但是,如果你自己实现它,我不会将数字存储为位序列,而是存储为像unsigned int这样的机器单词序列,以充分利用硬件ALU功能。因此,每个单词已经代表了一些位,而你的ALU知道如何将它们相乘。

注意,当你用n位(基数无关)乘以一个数字时,你会得到一个2n位的数字,例如99 * 99 = 9801(基数10),0xFF * 0xFF = 0xFE01(基数16)。因此,如果std::uintmax_tstd::uint64_t在您的系统上,您可以将您的号码存储为std::uint32_t的序列。当两个数字相乘时,将它们转换成std::uint64_t并将它们相乘。上面的32位将用于下一个更高数字的乘法运算。(实际上,您也可以直接将std::uintmax_t变量相乘,但是获得结果的高部分通常有点棘手,并且涉及内联汇编以访问相应的EDXRDX寄存器。)

有了这些知识,学校乘法方法的实现应该很简单:只需迭代a的所有数字a[i],并将每个数字与b相乘(不要忘记传播进位)。将结果向上移动i位,并将所有内容添加到最终结果中。

注意,该算法对于基本乘法的数量具有二次复杂度。如果您有(非常非常)大的数字,您还可以切换到更复杂的方法,如Karatsuba甚至FFT和Schönhage-Strassen。但是在这种情况下,我真的建议使用库。