How to explain this algorithm for calculating the power of a number?

后端 未结 6 1722
生来不讨喜
生来不讨喜 2020-12-15 01:12

I am currently reading Skiena\'s \"The Algorithm Design Manual\".

He describes an algorithm for calculating the power of a number i.e. calculate a^n.

相关标签:
6条回答
  • 2020-12-15 01:48

    The concept is simple. For example, compute the value of 38

    You can use the obvious way which is 38 = 3 x 3 x 3 x 3 x 3 x 3 x 3 x 3 which takes 7 multiplication operations. Or there is a better way.

    Let say that

    • If we know the value 34, we can compute 38 only in one multiplication operation, but we don't know the value of 34
    • If we know the value of 32, we can compute 34 in one multiplication operation.
    • And finally, we know that 32 can be easily compute by 3 x 3.

    Going backward, it only takes 3 multiplication to compute 38 instead of 7

    Here is the clearly view of the process:

       32 = 3 x 3 = 9
       34 = 32 x 32 = 9 x 9 = 81
       38 = 34 x 34 = 81 x 81 = 6,561
    

    Then, there is another problem, what if the power is odd number. For example: 39, how to deal with it? You can either do this

       39 = 3 x 38   or
       39 = 3 x 34 x 34
    

    Lets call the algorithm that continuously multiple the number as Method A, and algorithm that continuously divide the power by two as Method B. How good is method A comparing to method B? For a small number such as 38, there is not much significant improvement, even those, we minimize the number of multiplication, but we also slightly increase the number of division operation.

    So for 38

                   Multiplication   Division
       Method A:        7              0
       Method B:        3              3
    

    However, for the larger power, for example: 34,294,967,296

                   Multiplication   Division
       Method A:   4,294,967,295       0
       Method B:       32              32
    

    The difference is huge.

    0 讨论(0)
  • 2020-12-15 01:57
    x = power(a, n/2)
    

    will give you a^n/2. If even this whole statement is squared giving (a^n/2)^2. Now if n is odd, during n/2 a power of a^1 is lost so to get it back it is multiplied with a. This is according to the equation given.

    0 讨论(0)
  • 2020-12-15 02:03

    The function power(...) appears to be written the way it is to handle the effects of integer division. Recall that under integer division rules, the fractional part is discarded. This will only affect odd integers since an even integer divided by two produces no remainder.

    Thus whenever n is an even integer, the value computed for n/2 is exactly equal to n/2 and the top branch of the if can be taken: this is exactly what the equations stipulate.

    Whenever n is an odd integer, the value computed for n/2 is actually equal to floor(n/2). In other words, the statement:

    x = power(a,n/2)
    

    Has actually computed the result

    x = power(a,(n-1)/2)
    

    Meaning that you have permanently lost one 1 from your exponent, and simply returning x^2 will be short one power of a. Hence the bottom branch, which adds back in the power of a.

    If you imagine that instead of integer division, the computer was capable of perfectly lossless real number division, then you could rewrite the function as:

    function power( a, n )
    
        if (n = 0) 
            return(1)
    
        x = power(a,n/2)
    
        return x^2
    

    You can easily satisfy yourself that this is a simple recursive implementation of the second equation you provided in the question.

    0 讨论(0)
  • 2020-12-15 02:08

    This formula a^n = ((a^n/2)^2), which you understand dictates recursive algorithm.

    To get a^n you need first to calculate a^(n/2),
    To get a^(n/2), you need to calculate a^((n/2)/2),
    ... and so on, until (n/2/2/...2) reaches 0, which is the termination condition of the recursion.

    So, the recursive algorithm follows that formula exactly :

    to get power(a,n) you first recursively calculate power(a,n/2) and then return the result adjusting for n being odd/even number.

    There is also wikipedia article about this implementation.

    0 讨论(0)
  • 2020-12-15 02:10

    This function is recursive, meaning that when called, it is going to call itself over and over again until some final condition is met. In this case, there are three final conditions that will stop the function from calling itself and return the result.

    If I were you I would try to apply the algorithm manually on a couple of different values in order to understand.

    0 讨论(0)
  • 2020-12-15 02:12

    First of all, let's fix your algorithm:

    function power( a, n )
        if (n = 0) 
            return(1)
    
        x = power(a,n/2)
    
        if (n is even) 
            return(x*x)
        else 
            return(a*x*x)
    

    Say you want to calculate power(2,8), that is, 2^8 (^ is not XOR here, of course).

    • 1) (a=2, n=8). 2^8 = (2^4)^2, so we have to calculate x=2^4, and then x*x to yield the final result. We have to call power() again to get x. power(2,4).

    • 2) (a=2, n=4). 2^4 = (2^2)^2, so we have to calculate x=2^2, and then x*x to yield the final result. We have to call power() again to get x. power(2,2).

    • 3) (a=2, n=2). 2^2 = (2^1)^2, so we have to calculate x=2^1, and then x*x to yield the final result. We have to call power() again to get x. power(2,1).

    • 4) (a=2, n=1). 2^1 = (2^0)^2, so we have to calculate x=2^0, and then a*x*x to yield the final result. We have to call power() again to get x. power(2,0).

    • 5) (a=2, n=0). 2^0 = 1 because n is 0, so we have the value of x that is returned to step #4.

    • 4) (a=2, n=1, x=1). The final result for this step is a*x*x = 2*1*1=2, which is the value to be assigned to x in step #3.

    • 3) (a=2, n=2, x=2). The final result for this step is x*x = 2*2 = 4. This is the result to be assigned to x in step #2.

    • 2) (a=2, n=4, x=4). The final result for this step is x*x = 4*4 = 16. This is the result to be assigned to x in step #1.

    • 1) (a=2, n=8, x=16). The final result for this step is x*x = 16*16 = 256. This is the result to be returned by power(2,8).

    0 讨论(0)
提交回复
热议问题