使用位运算实现乘法和乘方运算

1、使用位运算乘法。

把一个乘数变为2进制后,使用位运算完成乘数的乘法。

/*
 * 输入:正整数k 和 正整数m
 * 输出:k*m
 */ 
__int64 km(__int64 k, __int64 m){
   __int64 x = k;
   int w = (int)floor(log(m) / log(2)) -1;
   __int64 e = 1 << w;
   for(int i=0; i<=w; i++){
       x <<= 1;
       if(m & e)
            x += k;
       e >>= 1;
   }
   return x;
}

2、使用位运算的乘方运算

指数变为2进制后,使用位运算完成乘方运算。

伪代码:


C++实现

/*
 * 输入:正整数v mod m 和 g mod m 
 * 输出:g^v mod m 
 */
__int64 gvmm(__int64 g, __int64 v, __int64 m){
    int w = (int)floor(log(v) / log(2)) - 1;
    __int64 e = 1 << w;
    __int64 x = g;
    for(int i=0; i<=w; i++){
        x = (x * x) % m;
        if(v & e){
             x = (g * x) % m;
        }
        e >>= 1;
    }
    return x;
}


乘方的测试:

使用普通算法和位运算算法比较。

#include <iostream>
#include <math.h>
#include <time.h>  
using namespace std;

/*
 * 输入:正整数v mod m 和 g mod m 
 * 输出:g^v mod m 
 */
__int64 gvmm(__int64 g, __int64 v, __int64 m){
    int w = (int)floor(log(v) / log(2)) - 1;
    __int64 e = 1 << w;
    __int64 x = g;
    for(int i=0; i<=w; i++){
        x = (x * x) % m;
        if(v & e){
             x = (g * x) % m;
        }
        e >>= 1;
    }
    return x;
}
/*
 * 验证结果的普通算法 
 */
int yanzheng(__int64 g, __int64 v, __int64 m){
    __int64 x = 1;
    for(int i=0; i<v; i++){
        x *= g;
        x %= m;
    }
    return x;
}

int main(){
    clock_t begin = clock();
    cout << yanzheng(23229,1892123, 23894)  << endl;
    clock_t end = clock();  
    double cost = (double)(end - begin) / CLOCKS_PER_SEC;  
    printf("putong : %lf seconds\n", cost);  
    begin = clock();  
    cout << gvmm(23229,1892123, 23894) << endl;
    end = clock();  
    cost = (double)(end - begin) / CLOCKS_PER_SEC;  
    printf("weiyunsuan: %lf seconds\n", cost);     
    system("pause");
}

按照程序中给出的稍复杂的乘方运算,其效率分别为(多次测量后都差不多这个数量级)

21963
putong : 0.071000 seconds
21963
weiyunsuan: 0.001000 seconds

差不多普通算法比位运算算法慢了50-70倍。



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值