Reputation: 1669
So I'm trying to implement a more efficient method of calculating 2^n
.
I know that you can split it up so that it is O(logn)
and it is easy to do using recursion. You keep dividing by 2 and multiply it by the lower power when its odd (or something like that). The problem is I wrote out my multiplication method by hand since its for big numbers. So it needs to return more than one parameter.
One solution I can think of is to make a pair which contains all the needed information. Other than that though I was trying to figure out how to write it using iteration. The only way I can see of doing is using some kind of data structure and then loop through dividing n by 2 and storing the value when n is odd. Then write a for loop and check at each iteration if the value is contained in the data structure. This seems to me like a relatively costly operation.
Is it possible that it would end up less efficient than the recursive version?
I'm doing this because:
Upvotes: 1
Views: 3400
Reputation: 9762
If you're going to work with big numbers, rather than reinventing the wheel, you probably should take a look at the GNU MP Bignum Library.
Regarding the recursion versus iteration question, the answer is that you can always write them to be equivalent; a recursive function that only calls itself as a tail call is as efficient as a while loop (provided that your compiler supports tail call optimization, but the most common compilers do). For instance, the tail-recursive version of the fast exponentiation function you are describing is (in pseudo-code):
function fastExp(base, exponent, accumulator) {
if(exponent == 0) {
return accumulator;
} else if(exponent % 2 == 0) {
return fastExp(base * base, exponent/2, accumulator);
} else {
return fastExp(base, exponent-1, base * accumulator);
}
}
Think of this recursive function as a loop, where the looping condition is exponent != 0
, and the recursive calls are like goto
s to the beginning of the loop. (You need to call it with accumulator = 1
when you start, by the way.) It is equivalent to the following:
function fastExp(base, exponent) {
var accumulator = 1;
while(exponent != 0) {
if(exponent % 2 == 0) {
base *= base;
exponent /= 2;
} else {
exponent -= 1;
accumulator *= base;
}
}
return accumulator;
}
So you can see that they are equivalent, and therefore will perform the same number of operations.
Upvotes: 6
Reputation: 24423
If you are storing everything as a sequence of 1 s and 0 s..i.e.. in Binary format, 2^n is simply a sequence of 0 s preceded by a single 1 , maybe you can use fact to simply your code
2^1 = 10
2^2 = 100
2^3 = 1000
2^4 = 10000
so on and so forth, Unless this is a learning exercise I would go with a standard arbitrary precision library like what Philippe suggested
Upvotes: 0