473,394 Members | 2,031 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,394 developers and data experts.

Calculating Large Exponents

jkmyoung
2,057 Expert 2GB
Calculating Large Exponents

Background: This is a quick article as to how to calculate the exponents of large numbers quickly and efficiently.
Starting with a basic multiplication algorithm, it gives subsequently faster algorithms and a few quick examples.
The techniques used in this article can be used in general mathematics, encryption, among other things.

In this article, the following conventions are used:
^ operator is to mean exponent, not the bitwise xor operation. So 2^3 is 2 cubed = 2 * 2 * 2.
* is multiplication
% is mod is modular division. Eg 10 mod 3 ≡ 1.
log2 stands for log base 2.

How do we calculate exponents? n^exp


************************************************** *******
Method 1: Simple Method
The first way we learn to calculate exponents is the expand and multiply out scenario. Let's take 7^13 as an example:

7^13 = 7*7*7*7*7*7*7*7*7*7*7*7*7
7 * 7 = 49
49 * 7 = 343
343 * 7 = 2401
2401 * 7 = 16807
16807 * 7 = 117649
117649 * 7 = 823543
823543 * 7 = 5764801
5764801 * 7 = 40353607
40353607 * 7 = 282475249
282475249 * 7 = 1977326743
1977326743 * 7 = 13841287201
13841287201 * 7 = 96889010407

Codewise:
Note in order to be concise, we'll set the following framework for all of the code in this article:
We create a power function:
long pow(long n, long exp);
Example of calling the function:
System.out.println("7 to the 13th power = " + pow(7,13));
where exp >= 1

Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   long power, prod;
  3.   prod = n; // hold the product of our multiplication.
  4.   for (power = 2; power <= exp; power ++)
  5.   {
  6.     prod *= n;  // prod = n^power
  7.   }
  8.   return prod;
  9. }
Although this works with small exponents, for larger exponents, it's quite a bit of work. Surely there must be a better way.
Number of multiplications:
exp - 1

************************************************** *******
Method 2: Divide and Conquer
Property of exponents:
if c = a + b
n^a * n^b = n^c

Applying to our example, we could have:
13 = 6 + 7
So 7^13 = 7^6 * 7^7!
7 * 7 = 49 = 7^2
49 * 7 = 343 = 7^3
343 * 7 = 2401 = 7^4
2401 * 7 = 16807 = 7^5
16807 * 7 = 117649 = 7^6
117649 * 7 = 823543 = 7^7
117649 * 823543 = 96889010407 = 7^6 * 7^7 = 7^13

Codewise, this might look like:
Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   long halfexp = exp / 2;
  3.   long power, prod, prod2;
  4.  
  5.   prod = n; // hold the product of our multiplication.
  6.  
  7.   for (power = 2; power <= halfexp; power ++)
  8.   {
  9.     prod *= n; //prod = n^power
  10.   }
  11.   if (exp % 2 == 0)
  12.     prod2 = prod;
  13.   else 
  14.     prod2 = prod *n;
  15.   return prod * prod2;
  16. }
prod eventually equals 7^6 and prod2 is set to 7^7.

Number of multiplications:
Calculating the base values: (exp / 2) - 1 + (exp % 2)
Final multiplication: 1
Total: (exp / 2) + (exp % 2)

This time, we have only 7 multiplications! (vs 12 earlier). Can we do better?


************************************************** *******
Method 3: Divide more and conquer
We can improve on this divide and conquer method even more! Divide 13 into more than 2 parts. Since 3^2 < 13 < 4^2,

and 3*4 < 13, divide it into 4 parts:
13 = 3 + 3 + 3 + 4
7^13 = 7^3 * 7^3 * 7^3 * 7^4
7 * 7 = 49 = 7^2
49 * 7 = 343 = 7^3
343 * 7 = 2401 = 7^4
343 * 343 = 117649 = 7^3*7^3 = 7^6
117649 * 343 = 40353607 = 7^6*7^3 = 7^9
40353607 * 2401 = 96889010407 = 7^9*7^4 = 7^13


The code for this part is a little tricky, so skip over it if it's too hard to understand. The hard part is figuring out how many parts you need.
Som examples of dividing the exponent into parts:
exp = 10, 10: 3, 3, 4
exp = 11, 11: 3, 4, 4
exp = 12, 12: 3, 3, 3, 3 (chosen this way as opposed to 4,4,4. Easier to code)
exp = 13, 13: 3, 3, 3, 4
exp = 14, 14: 3, 3, 4, 4
exp = 15, 15: 3, 4, 4, 4
etc...

Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   long sqroot = (long)(Math.sqrt(exp)); // truncates answer
  3.   long parts;  // number of terms we need
  4.   long power;  // current power 
  5.   long prod;   // to hold n^sqrt(exp)
  6.   long prod2;  // to hold n^(sqrt(exp) + 1)
  7.   long prod3;  // final answer
  8.   long terms;  // number of terms remaining to be multiplied
  9.  
  10.  
  11.   prod = n; // hold the product of our multiplication.
  12.  
  13.   for (power = 2; power <= sqroot; power ++)
  14.   {
  15.     prod *= n; //prod = n^power
  16.   }
  17.  
  18.   if (exp == sqroot * sqroot) // perfect square!
  19.     prod2 = prod;
  20.   else {
  21.     prod2 = prod * n;
  22.     parts = sqroot;
  23.     if (exp >= sqroot * (sqroot + 1)){
  24.       parts++;
  25.   }
  26.   prod3 = prod; // initialize our final answer. Work backwards for a little simplicity.
  27.  
  28.   //joined for loops.
  29.   for (terms = parts - 1; terms > exp % parts; terms--){
  30.        prod3 *= prod;
  31.   }
  32.   for (;terms > 0; terms--){
  33.        prod3 *= prod2;
  34.   }
  35.  
  36.   return prod3;
  37. }
Number of multiplications:
Calculating the base values: rounddown sqrt(n) (-1 if n is square)
Multiplying the base values together: round sqrt(n+0.25) - 1
Total multiplications: about 2 * sqrt(n)
6 multiplications!

************************************************** *******
Method 4: Binary exponents (2^k-ary method)
Now we've still been using method 1 to calculate the first parts of our calculation, which is slow. With this method, we do away with it altogether.
Take the binary of 13. 13 = 1101 in binary, or 8 + 4 + (0)*2 + 1 = 8 + 4 + 1

Now we calculate 7^1, 7^2, 7^4, 7^8.
7 = 7^1
7 * 7 = 49 = 7^1 * 7^1 = 7^2
49 * 49 = 2401 = 7^2 * 7^2 = 7^4
2401 * 2401 = 5764801 = 7^4 * 7^4 = 7^8

Now that we've calculated 7 to the power of a power of 2, note that 7^13 = 7^8 * 7^4 * 7^1
5764801 * 2401 = 13841287201 = 7^8 * 7^4 = 7^12
13841287201 * 7 = 96889010407 = 7^12 * 7 = 7^13


Codewise:
Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   Vector<long> powers;
  3.   long exp2 = exp; // copy of exp
  4.  
  5.   long prod = n; // holds n^2^index;
  6.   long prod2 = 1;
  7.  
  8.   while (exp2 > 0){
  9.     powers.add(n);
  10.     exp2 >>= 1;     // right shift 1.
  11.     prod *= prod;
  12.   }
  13.  
  14.   int power = 1; // n^(2^power)
  15.   while(exp > 0){
  16.     if ((exp & 1) != 0){ // 1 bit set
  17.       prod *= powers[power];
  18.     }     
  19.     power++;
  20.     exp >>= 1;
  21.   }
  22.   return prod;
  23. }
4b: Calculate as you go.
Notice that we're storing 7^1, 7^2, 7^4, 7^8. With this method, you don't have to store that extra space; we multiply as we go. Have 2 numbers, product and current. Product will calculate our temporary product, while current will calculate the powers of (powers of 2).

current = 7
13 is odd, so product = 7
current = 7*7 = 49 = 7^2
13's 2nd bit is not set, so product stays at 7.
current = 49 * 49 = 2401 = 7^4
13's 3rd bit is set, so product = 7 * 2401 = 16807 = 7 * 7^4 = 7^5
current = 2401 * 2401 = 5764801 = 7^8
13's 4th bit is set, so product = 16807 * 5764801 = 96889010407 = 7^5 * 7^8 = 7^13

Codewise:
Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   prod = 1;
  3.   while (exp > 0){
  4.     if ((exp & 1) != 0)
  5.        prod *= n;
  6.     n*=n;
  7.     exp >>= 1;
  8.   }
  9.   return prod;
  10. }
5 multiplications with this example.
However, keep in mind that this is with a small exponent (13). If calculating a large exponent, say 1000, it would take only about 20 multiplications! (Compared with at least 60 in the other methods)

Number of multiplications:
Calculating 7^2^log2(exp) : log2(exp)
Calculating the product : log2(exp) at most
Total: 2 * log2(exp)

Method 5. Sliding Window method:
This is an efficient variant of the (2^k-ary) method.
13 = 1101 in binary.
So we take the first digit: 1, then the first 2: 11, the first 3:110, and finally the whole sequence: 1101

7 = 7^1 ~ 1 in binary
Square it:
7 * 7 = 49 = 7^2 ~ 10 in binary.
49 * 7 = 343 = 7^3 ~ 11 in binary.
Square it:
343 * 343 = 117649 = 7^6 ~ 110 in binary.
Square it:
117649 * 117649 = 13841287201 = 7^12 ~ 1100 in binary
13841287201 * 7 = 96889010407 = 7^13 ~ 1101 in binary

Notice when we square a number, it's the same as adding a 0 to the end of the binary.
If the exponent has a 0 at the end, we can change the last digit to a 1 by multiplying by the number.

The code:
Expand|Select|Wrap|Line Numbers
  1. long pow(long n, long exp){
  2.   long multBit = Long.HighestSetBit(exp); //used to keep track of where we are in exponent, starting at highest bit.
  3.   long prod = n;
  4.  
  5.   for (multBit >>= 1; // ignore the first 1.
  6.        multBit > 0;
  7.        multBit >>=1)
  8.   {
  9.     prod *= prod;    
  10.     if ((multBit & exp) != 0)
  11.       prod *= n;
  12.  
  13.   }
  14.   return prod;
  15. }
See the YouTube demonstration of this method

Number of Multiplications
Same as method 4: At most 2 log2(exp)

************************************************** *******
Difference in number of multiplications
Expand|Select|Wrap|Line Numbers
  1. Method    1       2        3           4
  2. exp       O(n)    O(n/2)   O(sqrt(n))  O(log(n))
  3. 2         1       1        1           1
  4. 3         2       2        2           2
  5. 4         3       2        2           3
  6. 5         4       3        3           3
  7. 10        9       5        5           5
  8. 25        24      13       9           6
  9. 100       99      50       19          8
  10. 250       249     125      31          9
  11. 1000      999     500      62          11
  12. 2500      2499    1250     99          13
  13. 10000     9999    5000     199         15
  14. 25000     24999   12500    315         16
  15. 100000    99999   50000    631         18
  16. 250000    249999  125000   999         19
  17. 1000000   999999  500000   1999        21
  18.  
Look at the difference once we start getting into the millions. If your exponents are even bigger, you can see the difference it'll make!

Hopefully these tips will help you out when you have to calculate numbers like
30249327^30234922 % 3293527 or
928020^329010455 % 781323
Good luck!

Extra notes:
There are many other methods for calculating large exponents, but these are probably the first few basic ones. Of course, if your numbers are bigger than longs, than you can substitute your own BigInt classes.

If using these methods modularly, you can calculate the mod of each result, and the results will still apply. (Eg, if you're using this in a Riemann encryption scheme.)

Links:

Wikipedia
YouTube demonstration of method 5
Tags:
Powers, exponents, mod, encryption, large numbers,
Apr 28 '10 #1
2 59753
himmu7
10
Thank U so much for ur explanations
May 14 '10 #2
Motoma
3,237 Expert 2GB
This is great! Thanks for sharing.
May 21 '10 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

5
by: Ron Adam | last post by:
Hi, I'm having fun learning Python and want to say thanks to everyone here for a great programming language. Below is my first Python program (not my first program) and I'd apreciate any...
1
by: DJTB | last post by:
zodb-dev@zope.org] Hi, I'm having problems storing large amounts of objects in a ZODB. After committing changes to the database, elements are not cleared from memory. Since the number of...
1
by: Tom McCallum | last post by:
Is there any way to override the normal output of doubles? I am outputting numbers around 5 million and would like them to be formatted normally (5000000) instead of with exponents (5e06). What...
2
by: Alex Vinokur | last post by:
Does STL contain algorithms which generate (enable to generate) exponents, permutations, arrangements, and combinations for any numbers and words? -- Alex Vinokur mailto:alexvn@connect.to...
18
by: Zero | last post by:
Hi, I am calculating an integer to the pwer of a large integer, e.g. 2^5000. It turns out that the result I always get is zero. I am sure that the result is too large to store in such type...
6
by: Patrick McGovern | last post by:
Hi, quick question that's driving me nvts. how do i do exponential math in C#? -- Pat
2
by: Tim Marshall | last post by:
Wondering if anyone has any suggestions for this. Sometimes in the form reports my users run, a data sheet subform on a main form, with totals in text boxes with calculated controlsources...
4
by: enigmadude | last post by:
As many have heard, IronPython 1.0 was released. When I was looking through the listed differences between CPython and IronPython, the document mentioned that using large exponents such as 10 **...
4
by: Voltem | last post by:
Hey everyone I just registered. Seems like a nice community and all the other sentimental BS :). So my problem in a nutshell is I wanna write a programme that calculates Large factorials (lets say...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.