That is a lot harder problem than I expected. You can hack around with doubles and logs and stuff to get the answer quickly, in O(1), but it is just as prone to roundoff and problems as the above and accomplishes nothing at all. There are a couple of hacks that can approximate the value as well but approximate won't do.
I took a play-time crack at it and the best I could do for 64 bit ints raised to a positive int power was 13 multiplies. My approach did all 13 whether we need them or not, so its worse than the loop approach for small powers, and better for any power > 13.
Here is what I came up with. I am trying to see if there is a cleaner way to avoid the excess memory allocation & the unnecessary multiplies. I will play with it a bit more but here is what I have so far.
--edit, my trivial cases are out of order. I will fix that too, duh. Also, the high end multiplies can overflow for some values. I haven't handled that, obviously.
given that 2 can get to 64th power tops and 10 19th power tops and it falls off very rapidly from there, the loop is really the better solution. This is just messing around, admittedly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
long long intpwr(long long b, unsigned long long e)
{
//13 multiplies and 3 jumps works for 64 bit ints.
//2^64 is the largest that will fit in a 64 bit int.
//1^any and 0^ any are handled.
long long pwrs[65]; //wastes a lot of space, improve?
if(e > 64) return 0; //won't fit!
if(e == 0) return 1; //shortcuts for trivial cases
if(e ==1 || b == 1 || b==0 ) return b;
long long result = 1;
pwrs[0] = 1;
pwrs[1] = b;
pwrs[2] = b*b;
pwrs[4] = pwrs[2]*pwrs[2];
pwrs[8] = pwrs[4]*pwrs[4];
pwrs[16] = pwrs[8]*pwrs[8];
pwrs[32] = pwrs[16]*pwrs[16];
pwrs[64] = pwrs[32]*pwrs[32];
result *= pwrs[1&e];
result *= pwrs[2&e];
result *= pwrs[4&e];
result *= pwrs[8&e];
result *= pwrs[16&e];
result *= pwrs[32&e];
result *= pwrs[64&e];
return result;
}
|