Hi, I am trying to write a program that would take a number (in this case 2) and raise it to some power (in this case 16) and store every digit separately in a vector. I'll need for this to work with huge powers like 2000+. This is what I have so far:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> digits;
int number = 2, power = 16, counter = 0;
digits.push_back(number);
for (int i=0;i<power;i++)
{
if (((digits.size()-1)-counter) > 9)
{
digits.insert(digits.begin(), 0);
digits[0] += (digits.size()-1)/10;
digits[((digits.size()-1)-counter)] %= 10;
counter++;
}
else digits[digits.size()-1] *= number;
}
for (int i=0;i<digits.size();i++)
std::cout << digits[i];
}
This gets the value of 2^17 for some odd reason, instead of 2^16. Also it stops working after the value becomes bigger than 2^31 (at this, it returns a negative value, although the right one). After that it just gets a value of 0. I can't understand why this is, since I'm storing every digit separately there really shouldn't be any problem dealing with huge powers. Could someone look at my code and point out my mistakes? Thanks!
The reason why you are getting the wrong power is the line 7, which should go:
digits.push_back(1);
(otherwise you are adding one factor extra)
The reason why it doesn't work for numbers higher than 2^31 is that the condition in line 10 is never true. So, the array digits always ends up having a single element, which cannot be greater than 2^31.
If you want to solve this task by yourself, I suggest that you learn how to use a debugger.
Ok, you helped me. You told me to push back a 1 instead of the number and that line 10 is useless. Thank you for that.
You attempted to give me the solution without me even trying, I just had to pay for it so there's that.
Also, my new code works perfectly, in cpp.sh it can calculate up to 2^75000 without any problems. On my computer, it calculated 2^200000 in 140 seconds. Couldn't show the full result because of it being 60k+ digits long, but the first 20 or so digits were correct so I assume it works. No idea how you manage to get a crash.
EDIT: Found a problem in my code that prevents it from working when using bigger numbers like 50. It requires a fix in lines 14-16 and one function is unnecessary. Here's the fixed version:
I am using a GCC compiler (Code::Blocks IDE), true. Don't know how to define that thing you told me, but I think I figured it out. This is the fixDigits function:
1 2 3 4 5 6 7 8 9 10 11 12 13
void fixDigits(std::vector<int>& digits)
{
for (int j=digits.size()-1;j>=0;j--)
{
if (digits[0] > 9)
digits.insert(digits.begin(), 0);
if (j)
{
digits[j-1] += (digits[j]/10);
digits[j] %= 10;
}
}
}
Now it doesn't try to access digits[-1], but still gives the right answer. Interestingly, setting the for loop to run while j>0 doesn't work, but the above code does (even though I'm pretty sure doing either is equivalent to doing the other).
Then run the code to check whether it crashes or not.
Code::Blocks has a built-in debugger (gdb) accessible from the 'Debug' item on the menu.
I'm not sure whether the fixDigits function is actually correct now. There are several issues:
1. Inserting a new element will make the index j skip a digit.
2. If the digits[0] element changes, it's hard to see whether the first 'if' will be able to insert a new element correctly.
Here, now if it inserts a new element it won't skip an element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
void fixDigits(std::vector<int>& digits)
{
for (int i=digits.size()-1;i>=0;i--)
{
if (digits[0] > 9)
{
digits.insert(digits.begin(), 0);
i++; //I think this is better for now, because i = digits.size()-1; would start the checking process all over again when it's already done.
}
if (i)
{
digits[i-1] += (digits[i]/10);
digits[i] %= 10;
}
}
}
This doesn't crash the program when it runs with the define flag. Thanks for the help!
Oh, and all of the options in the debug menu are grayed out and I can't select them for some reason.