二进制数字的乘法

这两天一直在自学离散数学,有一道题目,花了我3个小时终于做出来了。特拿出来和大家交流

// 做一个二进制乘法的程序,输入b(n),b(n-1),...,b(0),b'(m),b'(m-1),...,b'(0)
// 输出c
/*

二进制的乘法表只有两种1×1=10,1×0=0,0×0=0
其中1×1=10是要进位的

利用和十进制相似的乘法原理,做出二进制的乘法,看例子
    111
×      11
----------
    111
   111
----------
  10101
*/
#include
< iostream >
#include
< cstring >
using   namespace  std;

// 首先归纳总结:对于a(n+1位),b(m+1位)的二进制数字相乘的结果不会大于n+m+2位
// 因为a <= 2^(n+1)-1 < 2^(n+1), b <= 2^(n+1)-1 < 2^(n+1)
// 所以a*b < 2^(n+m+2) (这个数字是n+m+3位的)
// 因此,a*b的位数<=n+m+2

// 以下的程序是根据输入的两数的排列是
// a(n),a(n-1),...,a(0)和b(m),b(m-1),...,b(0)来计算的
// 所以结果是倒过来的

/* 具体算法是这样的

                                                                               a(n),a(n-1)...a(0)
                                                                             × b(m),b(m-1)...b(0)
                                        ------------------------------------------------------
(1)                                                    b(0)a(n), b(0)a(n-1),...., b(0)a(1), b(0)a(0)
(2)                                        b(1)a(n), b(1)a(n-1), ...  , b(1)a(1), b(1)a(0)
                                            .
                                            .
                                            .
(m)                 b(m-1)a(n), b(m-1)a(n-1)
(m+1)  b(m)a(n), b(m)a(n-1)

结果放在一个c(m+n)...c(0)的数组中,这个数组中所有的值都初始化为0
步骤里面省略了carry的计算
[第一步]:
c(0)=c(0)+a(0)b(0)+carry
c(1)=c(1)+a(1)b(0)+carry
        ...
c(n)=c(n)+a(n)b(0)+carry
c(n+1)=c(n+1)+carry
carry=0(为了不让进位带入下一次的计算)

[第二步]:
c(1)=c(1)+a(0)b(1)+carry
c(2)=c(2)+a(1)b(1)+carry
        ...
c(n+1)=c(n+1)+a(n)b(1)+carry
c(n+2)=c(n+2)+carry
carry=0
        ...
[第m+1步]:
c(m)=c(m)+a(0)b(m)+carry
c(m+1)=c(m+1)+a(1)b(m)+carry
        ...
c(m+n)=c(m+n)+a(n)b(m)+carry
c(m+n+1)=c(m+n+1)+carry
carry=0

看清楚,实际上c(m+n+1)就是第m+n+2位
*/


/*   以下的程序是数字倒过来输入,结果也是倒过来输入的
int* binary_multiplication(int a[], int alen, int b[], int blen){
    int *c = new int[alen+blen];
    memset(c, 0, sizeof(int)*(alen+blen));//将结果的每一位都清0 
    int carry = 0;    //进位 
    int t;    //临时变量 
    for(int i = 0; i < blen; i++){
        for(int j = 0; j < alen; j++){
            //临时变量赋值为c[i+j] 
            t = c[i+j];
            //给c[i+j]赋值 
            c[i+j] = (c[i+j] + b[i]*a[j] + carry)%2;
            //存放进位 
            carry = (t + b[i]*a[j] + carry)/2;
        }
        c[i+alen]=carry;    //将当前最高位写上上一次加法中最后的进位
        carry=0;    //进位一定要在这里清零,不要带入到下一次的加法中去
    }
    return c;
}
*/

// 这个程序是数字是正过来输入,结果也是正过来输出的
int *  binary_multiplication( int  a[],  int  alen,  int  b[],  int  blen){
    
int   * =   new   int [alen + blen];
    memset(c, 
0 sizeof ( int ) * (alen + blen));     // 将结果的每一位都清0 
     int  carry  =   0 ;     // 进位 
     int  t;             // 临时变量
     for ( int  i  =  blen - 1 ; i  >=   0 ; i -- ){
        
for ( int  j  =  alen - 1 ; j  >=   0 ; j -- ){
            t 
=  c[i + j + 1 ];         // 临时变量赋值为c[i+j+1] 
            c[i + j + 1 =  (c[i + j + 1 +  b[i] * a[j]  +  carry) % 2 ;     // 给c[i+j]赋值 
            carry  =  (t  +  b[i] * a[j]  +  carry) / 2 ;     // 存放进位 
        }
        c[i]
= carry;     // 将当前最高位写上上一次加法中最后的进位
        carry = 0 ;     // 进位一定要在这里清零,不要带入到下一次的加法中去
    }
    
return  c;
}


int  main() {
    
int  a[] = { 1 , 1 , 1 , 0 , 0 , 0 , 0 };
    
int  asize  =   sizeof (a) / sizeof ( int );
    
int  b[] = { 1 , 1 , 1 , 0 , 1 , 1 };
    
int  bsize  =   sizeof (b) / sizeof ( int );

    
int   * result  =  binary_multiplication(a, asize, b, bsize);
    
    
for ( int  i  =   0 ; i  <  asize + bsize; i ++ )
        cout 
<<  result[i];
    
    cin.
get (); 
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值