-2

I'm a little new to programming, right now trying to find the largest prime factor of 600851475143, for Project Euler. My code won't compile when I actually try and do the Fermat Primality test.

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

int main () {

long long int num = 600851475143;
long long int factor = num / 2;

for (long long factor; factor > 0; factor--) {

    //Use Fermat primality test.

    if (num % factor == 0) {

        long long int testNum1 = rand() % 50 + 1;
        long long int testNum2 = rand() % 50 + 1;

        long long int test1 = (pow(testNum1, factor - 1) % factor);
        long long int test2 = (pow(testNum2, factor - 1) % factor);

        if (test1 == 1 && test2 == 1){

        cout << "The greatest prime factor is: " << factor;
        break;

        }
    }

}

return 0;
}
Daniel Strul
  • 1,458
  • 8
  • 16
Tim Gillis
  • 11
  • 1
  • When posting question about build problems/errors, always include the complete and unedited error output in the question body. Please edit your question to include it, and also to show where in your source the errors are. – Some programmer dude Oct 25 '15 at 19:12
  • 1
    This is a strange attempt at factorisation. I'm not sure how Fermat's primality test fits in there: it can tell you with a certain probability whether a given number is prime or not without telling anything about what its factors are if it is probably non-prime. You're also calculating huuuge numbers with `pow` (won't work), and iterating over potentially a lot of numbers (loop counts down from 600851475143/2 to 1). – WhiteViking Oct 25 '15 at 19:34
  • Ah, maybe you wanted to implement Fermat's factorisation method instead? https://en.wikipedia.org/wiki/Fermat%27s_factorization_method (The guy knew a thing or two about numbers :-) – WhiteViking Oct 25 '15 at 19:39

2 Answers2

2

Have a look at the documentation available for std::pow:

If any argument has integral type, it is cast to double

So in the expression pow(testNum, factor - 1), the arguments testNum and factor - 1 are promoted to double-precision floats, and the result then is a double-precision float.

You can't use the operator % on a double, as this operator is for integral types. Downcasting the result of pow might work, but you may easily run into integer overflow issues.

EDIT See this answer, regarding how to do this sort of big-integer computations.

Community
  • 1
  • 1
Daniel Strul
  • 1,458
  • 8
  • 16
  • I was taught that the algorithm is the Fermat primality test, which tests if a number is prime. Would that mean I would have to use another method with an integer this big? – Tim Gillis Oct 25 '15 at 20:21
  • 1
    Check the link I've included in the answer, it explains how you can do this kind of large-integer maths – Daniel Strul Oct 25 '15 at 20:58
1

@DanielStrul is correct and you should read its explaination to understand how do do modular exponentiation.

However, you don't really need to use the Fermat's test. Think that if this number is composite it will have at least one factor (not the biggest though) below sqrt(n).

As the density of primes is roughly x/ln(x) you can expect to find 72000, primes more or less (the formula is not exact), which is not that big.

Just compute all the prime numbers under one million (using a sieve). And try them one after the other. When you find a factor, keep divising n until you exhausted all powers of the current prime in the factorization of n.

When you exhausted all primes under a million (or when nequals 1), either n is not 1 and it is the biggest prime factor, or the biggest prime factor is the last prime you found in previous step.

fjardon
  • 7,921
  • 22
  • 31