I’m working on Project Euler to brush up on my C++ coding skills in preparation for the programming challenge(s) we’ll be having this next semester (since they don’t let us use Python, boo!).
I’m on #16, and I’m trying to find a way to keep real precision for 2¹°°°
For instance:
int main(){
double num = pow(2, 1000);
printf("%.0f", num):
return 0;
}
prints
10715086071862673209484250490600018105614050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Which is missing most of the numbers (from python):
>>> 2**1000
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376L
Granted, I can write the program with a Python 1 liner
sum(int(_) for _ in str(2**1000))
that gives me the result immediately, but I’m trying to find a way to do it in C++. Any pointers? (haha…)
Edit:
Something outside the standard libs is worthless to me – only dead-tree code is allowed in those contests, and I’m probably not going to print out 10,000 lines of external code…
If you just keep track of each digit in a char array, this is easy. Doubling a digit is trivial, and if the result is greater than 10 you just subtract 10 and add a carry to the next digit. Start with a value of 1, loop over the doubling function 1000 times, and you’re done. You can predict the number of digits you’ll need with
ceil(1000*log(2)/log(10)), or just add them dynamically.Spoiler alert: it appears I have to show the code before anyone will believe me. This is a simple implementation of a bignum with two functions, Double and Display. I didn’t make it a class in the interest of simplicity. The digits are stored in a little-endian format, with the least significant digit first.