Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterative implementation of pow(x, n)

Tags:

iteration

pow

I've found an iterative implementation of pow(x, n) which takes o(log n) time and constant space like below:

double pow(double x, int n) {
    double left = x;
    double right = 1;

    if (n<0) return 1/(x*pow(x,-n-1)); // Avoid binary overflow!!!!

    if (!n) return 1;

    while (n>1)
    {
        if (n%2==1) right *= left;
        left = left * left;
        n = n/2;
    }

    return left * right;
}

But I couldn't find any explanation of this algorithm. I understand the recursive solution using divide and conquer technique and I guess this solution uses similar trick. But I don't understand exactly why this works. Can anyone please explain this algorithm to me? Thanks!

like image 764
eaglesky Avatar asked Aug 29 '14 15:08

eaglesky


1 Answers

This algorithm decomposes the exponent, n, into the bits which represent the number.

The first line handles negative exponents, by computing the reciprocal, and reversing the sign of n. not that it pulls x^1 out of the pow() function by subtracting one,

if (n<0) return 1/(x*pow(x,-n-1));

The algorithm handles bits that are zero by observing that x^0 = 1 (see this line):

if (!n) return 1;

The while loop is repeatedly squaring x (see left=x; left = left*left;) as it divides the exponent n by 2. The right factor is used to compute the value of the i-th bit when set.

while (n>1)
{
    if (n%2==1) right *= left;
    left = left * left;
    n = n/2;
}

The loop terminates when n<=1, at which point the value left == x^(2*i) for the i-th bit, and right == x^(2*(i-1)) + ... x^(2*(i-n)), for the bits which are 'on'.

like image 182
ChuckCottrill Avatar answered Nov 02 '22 23:11

ChuckCottrill