`
frank-liu
  • 浏览: 1682400 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

快速指数运算方法

 
阅读更多

问题描述

    我们在一些常用的运算里免不了要计算某些指数函数。比如说给定两个正整数a, b,要求a**b,即a的b次方。这个问题看起来很简单,最直接的办法就是我连续乘以a,b次,得到的就是这个结果。这种方法的时间复杂度也比较低,相当于O(N)。实际上,我们还有更好的办法,使得它的时间复杂度达到O(logN)。

 

分析

    实际上这个问题本身并不是很复杂,从一开始看的时候似乎也能找到一点类似的苗头。比如说我们要求2 ** 7。我们知道,它可以拆分成2**4 * 2 ** 3。而对于2的4次方可以拆分成2**2 再做一次平方。对于一个理想的数字,比如说这个指数本身就是2的多少次方的,像4, 我们只要求出2**2,然后再在它的基础上求它自己的平方,这不就得到2**4了吗?而对于前面2的7次方这个数字,我们将它拆成了2**4乘以2**3。既然2的4次方可以这样来求,对于这些奇数来说呢?实际上我们可以进一步拆分的。2**3可以拆成2**2再乘以2。这样,它们都可以被拆分成一系列的数字给拼起来。

    这个过程似乎带来了一点思路。我们针对前面这个问题再深入的看一下,假设我们要求的这个数字的指数是7, 对它的拆分是将它拆成4和3。因为4是最接近它的2的指数,它可以通过两次求平方运算得到。而3呢,则需要再进一步按照这种方式来拆分。相当于找最接近它的那个2的指数。那么怎么找这个最接近它本身的2的指数呢?我们看7它的二进制表示形式:

    这是一个用4个位来表示的二进制数字形式。其实,它最接近的那个2的指数不就是为1的最高位么?那么我们最终要凑这个数字无非就是将各个为1的位对应的数字加起来。既然我们的目的是将这些数字加起来,那么完全就没有必要考虑从左往右的拆分了。我们完全可以这样来求,看一个数字的某个位是否为1,比如我们从最低位开始。如果是1, 我们就加上一个2**0,也就是1, 而再往后一位对应的第1位的位置, 如果这一个位置也是1的话,则加一个2**1的值。后面依次类推,对应的分别是2**2, 2**3等等。我们这里相当于得出来一个根据二进制数字来凑这个整数的过程。类似的伪代码如下:

 

while(b != 0) {  // 如果这个要凑的数字不为0
    r = b % 2;    // 取出最低位
    b /= 2;
    k = 0;
    if(r == 1)
        sum += (2 ** k)  // 如果当前的位为1, 则表示当前位有数字,加上对应的2的k次方。
    k++;
}

    这里的过程是根据2进制数来求对应整数的。而我们这里具体的问题是要求对应的指数。这里也比较简单,我们对应的更加高的一个位相当于原来的数字对它本身做了个平方。而如果对应的这个位为1, 我们就将它乘以原来的一个数字,相当于前面的相加变相乘。所以套用这个框架,我们就可以很容易得到如下的代码:

 

public static long calculate(int a, int b) {
        if(a <= 0 || b <= 0)
            throw new IllegalArgumentException();
        int r;
        long x = a;
        long y = 1;
        while(b != 0) {
            r = b % 2;
            b = b / 2;
            if(r == 1)
                y *= x;
            x = x * x;
        }
        return y;
    }
     这里结合了两个部分,首先要将这个数字拆分成对应的2进制的形式。不过不需要完整的拆开,每次用b % 2得到的就是当前最低位的值。而将b / 2则相当于b的二进制数字向右移动一位,将第二位的数字变成最低位。这样每移一次我们将对应的底数求平方,就对应到这个位的值。

    从时间复杂度的角度来看,因为我们在循环里每次对这个指数向右移动1位。这个数字对应的是logN个二进制位。所以我们总共遍历的次数为logN。也就是时间复杂度为O(logN)。

 

总结

    求指数函数的快速方法无非是用到了几个典型的数学特性。我们知道,对一个数的指数求平方的话,相当于对指数乘以2。所以问题的根源就归结到我们要怎么样来凑出这个给定的指数值。而如果我们对于数字的2进制表示形式比较清楚的话,会发现它们可以归结到一个将数字转化成二进制的样式的问题。

 

参考材料

Mathematics for computer science

  • 大小: 2.8 KB
分享到:
评论

相关推荐

    基于组合_移位的指数运算FPGA实现方法

    基于组合-移位的指数运算FPGA实现方法涉及的IT知识点相当丰富,主要包含以下几个方面的详细说明: 1. FPGA(现场可编程门阵列):是一种可以通过特定软件进行编程配置的数字集成电路。FPGA具有可重配置性、并行处理...

    基于组合-移位的指数运算FPGA实现方法.pdf

    查找表是FPGA实现指数运算中的一种常用技术,通过预先计算并存储指数函数的值,以便于快速查表实现函数值的获取。但查找表的大小与指数函数在X轴取值范围的大小成正比,当要求运算精度较高时,查找表将变得庞大,这...

    电子政务-用硬件实现指数运算的电路.zip

    硬件实现指数运算的电路设计是一种优化计算性能的方法,尤其在处理大量复杂数据时,这种技术能够显著提高系统的运算速度和效率。本压缩包“电子政务-用硬件实现指数运算的电路.zip”提供了一份详细的技术资料——...

    密码学指数算法源代码

    传统的指数运算方法(如朴素的幂运算)在处理大整数时效率较低,因此需要优化算法。其中,最常用的优化算法有分治法的快速幂(Fast Exponentiation)和滑动窗口法。 1. **快速幂算法**:快速幂的基本思想是将指数b...

    RSA算法实现

    为了提高效率,通常采用二进制快速指数运算方法。该方法的核心思想是将指数\( e \)转换成二进制形式,即: \[ e = ∑_{i=0}^{n-1} a_i 2^i \] 其中\( a_i \)可以取0或1。那么\( m^e \)可以表示为: \[ m^e = m^{...

    指数算法运算文件指数算法运算文件指数算法运算文件指数算法运算文件指数算法运算文件

    指数运算通常是计算一个数的另一个数次幂,例如2的3次方(2^3)或e的π次方(e^π)。本文件集合主要探讨的是关于指数算法的运算方法和实现细节。 指数算法的核心在于高效地计算a^n,其中a是底数,n是指数。在基础...

    KeilC-51下快速小数运算算法.PDF

    3. **查表法**:对于一些复杂的运算,如指数和对数,可以预先计算出一系列结果并存储在查找表中,运行时直接查表,避免了复杂的计算过程。 4. **近似算法**:使用舍入或者截断策略,以及如牛顿迭代法这样的近似算法...

    算法文档无代码置换群快速幂运算研究与探讨

    首先,标题中的“算法文档无代码置换群快速幂运算研究与探讨”指向了一篇专业文档,该文档聚焦于研究置换群理论中的快速幂运算,并以无代码形式阐述其理论与方法。这里我们可以提取以下知识点: 1. 算法:算法是一...

    C++使用string的大数快速模幂运算(6)

    例如,假设我们需要计算a的m次方,那么可以将m表示为二进制形式,然后使用快速指数运算来计算结果。 在代码中,我们实现了快速模幂运算的算法,包括减法、乘法、取模和除法运算。例如,减法运算可以使用minus函数来...

    近似指数计算

    对于指数函数,可以在log空间中进行二分查找,再利用指数运算的性质e^(a+b) = e^a * e^b来组合结果。 3. **CORDIC算法**(坐标旋转数字计算机):这是一种硬件友好的算法,特别适用于微处理器和嵌入式系统,它通过...

    电子功用-数据的防攻击方法及装置、RSA模幂运算方法、装置和电路

    它的核心运算包括模幂运算,即对一个数进行模意义下的指数运算。在加密过程中,公钥用于加密明文,私钥用于解密密文。模幂运算的效率直接影响到RSA算法的性能,因此,优化模幂运算的方法和装置对于提高加密速度和...

    运算方法和运算部件PPT学习教案.pptx

    运算方法和运算部件是计算机科学中的基础概念,特别是在数字电路和计算机体系结构中至关重要。本教程主要涵盖了数据的表示方式、带符号数的运算、二进制乘法和除法以及浮点数运算,同时也涉及到了运算部件的作用和...

    基于FPGA的实时金融指数行情并行计算方法.pdf

    基于FPGA的实时金融指数行情并行计算方法,涉及一种实时金融指数行情的计算分析方法,尤其对高频的金融期货交易信息进行并行行情分析。将期货套利快速分析、合约推导和行情更新等功能移植到FPGA硬件平台上并行加速...

    高精度浮点数幂指运算

    对于幂指数运算,常规的快速幂(Fast Exponentiation)算法在高精度环境下依然适用。快速幂的基本思想是将指数分解为二进制形式,然后通过不断地乘以自身和平方来减少计算次数。在高精度环境中,这意味着我们需要...

    6 MATLAB运算方法.zip

    在MATLAB中,运算方法多样且高效,可以帮助用户快速解决复杂问题。以下是一些核心的MATLAB运算方法: 1. **基本运算符**:MATLAB支持常规的算术运算符,如加(+), 减(-), 乘(*), 除(/), 余数(%),以及幂运算(^)。...

    行业-电子-模幂运算电路和系统及模幂运算方法的说明分析.rar

    在电子工程领域,模幂运算电路和系统以及模幂运算方法是数字信号处理中的关键组成部分。模幂运算,顾名思义,就是对一个数进行乘方运算,并限制结果在特定模数范围内,广泛应用于无线通信、数字信号处理、加密算法和...

    二元运算的错数

    【二元运算的错数】是指在进行加减乘除、对数及幂指数运算时,由于数值计算误差导致计算结果中的错误有效数字的数量。这一概念由赵世忠在研究误差的积累与传播机制时提出,对于理解和评估计算模型的误差具有重要意义...

    matlab基础编程;4 精通MATLAB运算方法和求积分.zip

    本资料主要针对MATLAB的基础编程和运算方法,以及如何进行积分计算进行深入讲解。 1. **基础编程概念**: - **变量与数据类型**:MATLAB支持多种数据类型,包括标量、向量、矩阵、数组等,理解这些基本概念是编程...

Global site tag (gtag.js) - Google Analytics