can someone explain how to let operations like 3^9999 work in c++, as i found, if number is too long it causes problems. I've heard that there is a way to work it out. (Please do not suggest any external libraries)
-
1If `^` means exponentiation, you need a big-integer library. If you don't want to use an external library, you have to write your own. – Daniel Fischer Sep 05 '12 at 18:16
-
although I won't suggest you use a big number library, you could look at the code they use? – Jimmy Sep 05 '12 at 18:17
-
9When the best solution is to use an external library, but people ask for no suggestions of external libraries, do you know what the solution becomes? *Implement on your own what was already implement in an external library*. – R. Martinho Fernandes Sep 05 '12 at 18:18
-
Use Java – Petar Minchev Sep 05 '12 at 18:18
-
1Nonsense question. Standard function `double pow( double base, double exponent);` from
gives me 5.4378339511420862476775224306038e+4770. – Öö Tiib Sep 05 '12 at 18:22 -
1@ÖöTiib I'm *guessing* since the OP bothered to ask the question, they want all the digits, though. Why the "do not suggest any external libraries" is beyond me though, (and smells a little of homework?) – lc. Sep 05 '12 at 18:24
-
1@Ic makes sense. Probably someone down-voted it because we have to guess. – Öö Tiib Sep 05 '12 at 18:26
-
it was asked on olympiad when i was at high school, i couldn't solve it and still wondering how to solve it :) The only suggestion i have is to place the result into array (that is what told the guy who solved it) – bla2e Sep 05 '12 at 18:27
-
The units digit is 1. The rest is left as an exercise. :-) – Happy Green Kid Naps Sep 05 '12 at 18:48
-
@ÖöTiib, a standard double can't go beyond 1.8e+308 [according to Wikipedia](http://en.wikipedia.org/wiki/IEEE_754-1985). What version of C++ are you using? – Mark Ransom Sep 05 '12 at 18:53
-
@Mark Ransom the C++ standard does not certainly specify that. Seems that mine is using 80 bit doubles (x86 extended precision format). – Öö Tiib Sep 05 '12 at 19:06
-
1@HappyGreenKidNaps Nope, the units digit is 7 (3^4 % 10 = 1, 9999 % 4 = 3, 3^3 % 10 = 7). – Daniel Fischer Sep 05 '12 at 19:44
-
@DanielFischer -- Mea culpa. I was thinking of 3^10000. – Happy Green Kid Naps Sep 05 '12 at 20:42
4 Answers
Split your problem into three problems.
1) First make solution how to multiply very long integers.
2) turn 9999
into binary 10011100001111
. There are 14 bits. 8 bits are set. Set bits (in order from end) mean that 9999 = 1 + 2 + 4 + 8 + 256 + 512 + 1024 + 8192
. The factors are useful since 3^2 = 3^1 * 3^1
etc. in general n^(2^m) = n^(2^(m-1)) * n^(2^(m-1))
. You can calculate the factors in cycle starting from 3^1 = 3
, that makes 13 multiplications.
3) Calculate 3^9999 = 3^1 * 3^2 * 3^4 * 3^8 * 3^256 * 3^512 * 3^1024 * 3^8192
by multiplying the factors into result. That makes 7 more multiplications.
For calculating 3^9999 you need 20 very long integer multiplications.

- 10,809
- 25
- 44
-
-
It took me a minute to realize the optimization versus my own answer - `3^2=3^1*3^1`, `3^4=3^2*3^2` etc. You have 12 multiplications to get the factors `3^1` to `3^(2^13)` and 7 more to multiply the 8 required factors. – Mark Ransom Sep 05 '12 at 21:27
Since you have asked for a solution that doesn't rely on a library, you'll have to do it the hard way.
Create a function that multiplies two arrays of digits together. You'll need about log10(3)*9999
digits for this, or 4771. Initialize two arrays with all zeros and a 3, then multiply the first by the second for 9998 times.

- 299,747
- 42
- 398
- 622
-
so, i'll have 2 arry, and then multiply them... 1) why one of them should be all 0 and another all 3? and where i should store the result? – bla2e Sep 05 '12 at 18:29
-
@bla2e, what I meant was to start both arrays with 4770 zeros and a single 3 at the end. Do the multiply in place so that the result is in one of the two arrays. – Mark Ransom Sep 05 '12 at 18:38
Hope you're not looking for optimisation...
int N = 9998;
int M = 5000;
int arr [M];
for ( int j = 0 ; j < M ; ++j )
arr[j]=0;
arr[M-1] = 3;
for ( int i = 0 ; i < N ; ++i ) {
for ( int j = 0 ; j < M ; ++j )
arr[j] = arr[j]*3;
for ( int j = M-1 ; j > 0 ; --j ) {
arr[j-1] = arr[j-1] + arr[j]/10;
arr[j] = arr[j]% 10;
}
}
for ( int j = 0 ; j < M ; ++j )
std::cout << arr[j];

- 1,974
- 2
- 21
- 28
Any ideas on how I could make it uglier so his professor won't accept it? =]
#include <stdio.h>
#include <string.h>
int main()
{
unsigned char ds[9999];
unsigned char c;
ds[0] = 3;
bzero(ds+1, 9998);
for(int p = 2; p <= 9999; p++)
{
c = 0;
for(int d=0; d<p/2+1; d++)
{
ds[d] = ds[d] * 3 + c;
c = ds[d] / 10;
ds[d] = ds[d] % 10;
}
}
int d = 9998;
for(; d>=0; d--)
if(ds[d] != 0)
break;
for(; d>=0; d--)
printf("%d", ds[d]);
printf("\n");
}

- 181,706
- 17
- 308
- 431

- 11,583
- 10
- 52
- 97
-
there is no professor, just my own curiosity, so u're free to make it as ugly as you wish :) – bla2e Sep 05 '12 at 19:29