tags:

views:

186

answers:

2

Hi there, I'm pretty new to programming and so I"m making this program in C++ that will take a number and find it's prime factors, which works great! Unless it's too big for an int variable. Now then I tried to change all of the int variables to long long variables so it wouldn't matter, but this doesn't seem to fix the problem. The program is as follows:

#include <iostream>

using namespace std;

bool prime (long long recievedvalue) { //starts a function that returns a boolean with parameters being a factor from a number
    long long j =1;
    long long remainderprime = 0;
    bool ended = false;
    while (ended == false){ //runs loop while primality is undetermined
        if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
            //not prime
            return false;
            break; // breaks loop
            }
        remainderprime=recievedvalue%j; //gives a remainder for testing
        if ((remainderprime==0 && j>2) && (j!=recievedvalue || j == 4)){ //shows under which conditions it isn't prime
        ended=true;
        //not prime
        return false;
        }
        else if (j==1){
            j++;
            }
        else if ( recievedvalue==2 || j==recievedvalue ){ // shows what conditions it is prime
          ended = true;
          //prime
          return true;
            }
            else {
            j++;
            }
        }
    }


long long multiple(long long tbfactor){ //factors and then checks to see if factors are prime, then adds all prime factors together
    //parameter is number to be factored
    long long sum = 0;
    bool primetest = false;
    long long remainderfact;
    long long i=1;
    while (i<=tbfactor){ //checks if a i is a factor of tbfactor
        remainderfact=tbfactor%i;
        if (remainderfact==0){ //if it is a factor it checks if it is a prime
            primetest = prime(i);
        }
        if (primetest ==true){ //if it is prime it add that to the sum
            sum += i;
            primetest=false;
        }
        i++;
    }
    return sum;
}

int main()
{
    long long input;
    long long output;
    cout << "Enter a number > 0 to find the sum of all it's prime factors: ";
    cin >> input;
    if (input == 0 || input <= 0){
        cout << "The number you entered was too small."<< endl << "Enter number a number to find the sum of all it's prime factors: ";
    cin >> input;
        }
    output = multiple(input);
    cout << output << endl << "finished";
    return 0;
}

Now then to be sure, the problem does the same thing whether or not it's a int or not. Also like I said I"m new to programming, and C for that matter so I look forward to your easily understandable replies. :)

+3  A: 

I'm willing to be that your program IS running. I'm sure that someone is going to pop on and give you the answer in a heartbeat, but I'm hoping that it doesn't happen so that you get to experience the same thing that I did when I ran into the problem YEARS ago.

Do this: start with 1, and work up from there using powers of 2 (1, 2, 4, 8, 16, etc.) and just keep going, doubling the input number each time. When does it "stop running?" Does it get progressively slower?

Please comment back on my post or on your own, or edit your own, or post an answer, whatever it is you're allowed to do with only 56 rep. If the community will allow it (and of course I would like the community to further the lesson), I'd like to gently push you to the answer through a series of back-and-forth steps feedback rather than the typical fashion, since this is an obvious unique learning opportunity.

San Jacinto
Okay I"ll try that, I also would much rather learn! So I hope they allow it too, I'll post back in a bit.
Samuraisoulification
Okay so, right now my computer is compiling the value for 8,589,934,592 and it's taking forever! Seeing as the number I want is 600 billion.... I fear how long that will take.
Samuraisoulification
@Samuraisoulification You're probably seeing that it's getting progressively longer to take as time goes on. It's only going to take longer the larger the input number is. This means that as the number increases, the program must do more work to run to completion, so it takes longer. Can you see something in your code that would take a long, long time? Don't think along the lines of tweaks you can do to make a couple lines run faster, think along the lines of reducing redundancy. Do you see anywhere in your code where you're computing the same exact things over and over?
San Jacinto
Yeah, essentially once it finds a factor (no matter how big or how long it took to iterate up to that factor, it has to iterate a new loop up to that factor, so it takes an extra long time?
Samuraisoulification
Exactly! Nice work! Now, can you think of a way to overcome this problem?
San Jacinto
I think so, but it's gonna take a while, I'm gonna think of a new approach and get back to you.
Samuraisoulification
@Samuraisoulification Boil it down to the root problem. You are computing the prime values over and over. You can't _not_ compute them; you need them for your algorithm. Your algorithm would also fail in the general case if you simply cached all of the primes in a file or something. A middle-ground approach would be to save them somewhere the first time you've computed them. If you also remember the last number you examined for primality, you will never need to do any real computation below that number again since you already did it once and remembered it.
San Jacinto
@Samuraisoulification how's it coming?
San Jacinto
+2  A: 

If you are trying to find if a number is a prime or not, here is a fast solution,

#include <iostream>

using namespace std;

#define ullong unsigned long long

bool prime (ullong x)
{
    if(x <= 1)
        return false;

    ullong s = (ullong)sqrt(x);

    for(ullong i=2;i<=s;i++)
        if(x%i == 0)
            return false;

    return true;
}
Prabhu Jayaraman
This is the type of thing I was referring to. Is there a chance you can delete your answer until later when he discovers this part of the issue, and then you can undelete it and reintroduce it?
San Jacinto
Use a typedef instead of that nasty #define
John Dibling
why iterate to sqrt(x)+1 ? isn't iterating to sqrt(x) fine?
KennyCason
I think the `sqrt(x)+1` is to avoid problems with 1 and/or 2 being false positives. _(I'm not positive though. Haven't worked with primes in a while)_
vlad003
since he is dealing with an `unsigned long long` the sqrt(2) which is less than 2, is floored to 1. Therefore the for loop never gets entered and will return true for 2.
KennyCason