设为首页 加入收藏

TOP

判断一个数是否为素数(二)
2013-07-23 09:09:03 来源: 作者: 【 】 浏览:2046
Tags:判断 一个数 是否 素数


    4.快速计算乘方的算法
    如计算2^13,则传统做法需要进行12次乘法。
    [cpp]
    /*计算n^p*/
    unsigned power(unsigned n,unsigned p)
    {
    for(int i=0;i<p;i++) n*=n;
    return n;
    }
    /*计算n^p*/
    unsigned power(unsigned n,unsigned p)
    {
    for(int i=0;i<p;i++) n*=n;
    return n;
    }
    该死的乘法,是时候优化一下了!把2*2的结果保存起来看看,是不是成了:
    4*4*4*4*4*4*2
    再把4*4的结果保存起来:16*16*16*2
    一共5次运算,分别是2*2、4*4和16*16*16*2
    这样分析,我们算法因该是只需要计算一半都不到的乘法了。
    为了讲清这个算法,再举一个例子2^7:2*2*2*2*2*2*2
    两两分开:(2*2)*(2*2)*(2*2)*2
    如果用2*2来计算,那么指数就可以除以2了,不过剩了一个,稍后再单独乘上它。
    再次两两分开,指数除以2: ((2*2)*(2*2))*(2*2)*2
    实际上最后一个括号里的2 * 2是这回又剩下的,那么,稍后再单独乘上它 现在指数已经为1了,可以计算最终结果了:16*4*2=128
    优化后的算法如下:
    [cpp]
    unsigned Power(unsigned n,unsigned p)
    {
    unsigned main=n; //用main保存结果
    unsigned odd=1; //odd用来计算"剩下的"乘积
    while (p>1)
    {//一直计算,直到指数小于或等于1
    if((p%2)!=0)
    {// 如果指数p是奇数,则说明计算后会剩一个多余的数,那么在这里把它
    乘到结果中
    odd*=main; //把"剩下的"乘起来
    }
    main*=main; //主体乘方
    p/=2; //指数除以2
    }
    return main*odd; //最后把主体和"剩下的"乘起来作为结果
    }
    unsigned Power(unsigned n,unsigned p)
    {
    unsigned main=n; //用main保存结果
    unsigned odd=1; //odd用来计算"剩下的"乘积
    while (p>1)
    {//一直计算,直到指数小于或等于1
    if((p%2)!=0)
    {// 如果指数p是奇数,则说明计算后会剩一个多余的数,那么在这里把它
    乘到结果中
    odd*=main; //把"剩下的"乘起来
    }
    main*=main; //主体乘方
    p/=2; //指数除以2
    }
    return main*odd; //最后把主体和"剩下的"乘起来作为结果
    }
    够完美了吗?不,还不够!看出来了吗?main是没有必要的,并且我们可以有更快的代码来判断奇数。要知道除法或取模运算的效率很低,所以我们可以利用偶数的一个性质来优化代码,那就是偶数的二进制表示法中的最低位一定为0!
    完美版:
    [cpp]
    unsigned Power(unsigned n, unsigned p)
    { // 计算n的p次方
    unsigned odd = 1; //oddk用来计算"剩下的"乘积
    while (p > 1)
    { // 一直计算到指数小于或等于1
    if (( p & 1 )!=0)
    { // 判断p是否奇数,偶数的最低位必为0
    odd *= n; // 若odd为奇数,则把"剩下的"乘起来
    }
    n *= n; // 主体乘方
    p /= 2; // 指数除以2
    }
    return n * odd; // 最后把主体和"剩下的"乘起来作为结果
    }
    unsigned Power(unsigned n, unsigned p)
    { // 计算n的p次方
    unsigned odd = 1; //oddk用来计算"剩下的"乘积
    while (p > 1)
    { // 一直计算到指数小于或等于1
    if (( p & 1 )!=0)
    { // 判断p是否奇数,偶数的最低位必为0
    odd *= n; // 若odd为奇数,则把"剩下的"乘起来
    }
    n *= n; // 主体乘方
    p /= 2; // 指数除以2
    }
    return n * odd; // 最后把主体和"剩下的"乘起来作为结果
    }
    ========================================================

            

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇引用计数的智能指针shared_ptr 下一篇C++ 函数声明中指定,默认参..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: