@carleye
Below is the factorial function that I linked to (and @Chervil also). I have spread it out and added more comments than I would usually do. The key thing is that it uses a vector<int> to store individual digits (starting from the "right") and it basically works by mimicking "long multiplication" - remember school before you were allowed a calculator!
This one uses recursion, but that's not vital: you could use a loop.
You obviously don't need a factorial ... but, in principle, you only need to make minor changes to THREE lines:
(1) The end of the recursion for the factorial is 1! = 1 - you could use either 2
0=1 or 2
1 = 2 (your choice) - adjust
line 18
(2) The recursion for the factorial is n! = n * (n-1)! - you will need 2
n = 2 * 2
n-1 - adjust
line 30
(3) You want 2
1000, not 2
100 - adjust
line 44
Cosmetically, it would then make sense to rename Factorial to PowerOf2 or something.
This is by no means the only way of doing the problem.
- you could use a loop rather than recursion;
- vector<int> is quite profligate, using 4 bytes for each digit; you could use vector<short>, vector<char> or string
- you could do the problem by repeated long addition (@Chervil's original suggestion) rather than long multiplication; I only prefer the latter because it makes it easier to generalise to powers of other numbers;
- you could shortcut the number of multiplies; e.g. 2
1000 = (2
10)
100 = 1024
100
- you could (with more work) write a "proper" high-precision integer class in binary (good luck!)
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
#include <iostream>
#include <vector>
#include <numeric> // for accumulate
using namespace std;
//*******************************************************************
// Uses recursion: n! = n * (n-1)! *
// i.e. Factorial(n) = n * Factorial(n-1) *
// with end of recursion Factorial(1) = 1 *
// *
// Because the number is too large for a normal integer, the digits *
// of the result are returned (in reverse order) in a vector<int> *
//*******************************************************************
vector<int> Factorial( int n )
{
if ( n == 1 ) return vector<int>{ 1 }; // End of the recursion: Factorial(1) = 1
vector<int> result; // Will store, and eventually return, the answer.
vector<int> last = Factorial( n - 1 ); // Recursive call for previous value, Factorial(n-1)
int size = last.size(); // Number of digits in Factorial(n-1).
// With normal long multiplication, each will be multiplied by n in turn
int i = 0; // i will be the index of the digit (i=0 holds ones, i=1 holds tens, i=2 holds hundreds etc.)
int carry = 0; // Any 'carry' into the next tens column for multiplication; obviously 0 to start.
while ( i < size || carry > 0 ) // i < size makes sure each digit is multiplied by n
{ // Any carry > 0 goes into the next column if necessary
if ( i < size ) carry += n * last[i]; // Multiplies the digit in last[i] by n, and adds to any existing carry (which may be 0)
result.push_back( carry % 10 ); // Done this digit multiply, so put in result
carry /= 10; // Go into the next tens column (e.g 16 would give 6 carry 10, or add 1 to next column)
i++; // Move to next digit
}
return result; // Returns the vector<int> representing the factorial
}
//======================================================================
int main()
{
vector<int> F = Factorial( 100 ); // Call the function and put the result in a vector<int>
for ( int j = F.size() - 1; j >= 0; j-- ) cout << F[j]; // Write the result (note: digits were stored in reverse order)
cout << "\nNumber of digits = " << F.size() << '\n'; // Number of digits is just the number of elements in this vector<int>
cout << "Sum of digits = " << accumulate( F.begin(), F.end(), 0 ) << '\n'; // Add digits with std::accumulate()
// (or you could write your own function to sum them)
}
|