int main(int argc, char **argv) { char line[INTEGER_LIMIT]; if (argc > 1) strncpy(&line[0], argv[1], INTEGER_LIMIT); else if (scanf("%s\n", &line[0]) != 1) { fprintf(stderr, "factor: unable to read number from stdin\n"); return 1; } mpz_t n; mpz_init(n); if (mpz_set_str(n, &line[0], 0) == -1 || mpz_cmp_ui(n, 1) < 0) { fprintf(stderr, "factor: input must be a positive integer\n"); mpz_clear(n); return 1; } if (mpz_cmp_ui(n, 1) == 0 || mpz_probab_prime_p(n, MILLERRABIN_REPEATS) > 0) { gmp_printf("%Zd: %Zd\n", n, n); mpz_clear(n); return 0; } mpz_t t; mpz_init(t); mpz_sqrt(t, n); struct factors *f = factors_create(); struct prime_sieve *ps = prime_sieve_create(MIN(TRIALDIVISION_LIMIT, mpz_get_ui(t))); if (mpz_perfect_square_p(n)) { factors_push(f, t); factors_push(f, t); } else { mpz_set(t, n); factors_push(f, t); } /* run trial division to find find small factors */ while (factors_remove_composite(f, t) && trial_division(t, f, ps)); prime_sieve_destroy(ps); /* run quadratic sieve until factorized into only prime numbers */ while (factors_remove_composite(f, t) && quadratic_sieve(t, f, QUADRATIC_SIEVE_SIZE)); factors_sort(f); print_result(n, f); mpz_clears(n, t, NULL); factors_destroy(f); return 0; }
int main() { int limit = 60; primeWithin(primes, limit); primes.push_back(-1); sort(primes.begin(), primes.end()); //this prime vector is special, -1 included in the first place, //when primes are used as regular prime vector start from 1 generate_congmap(congmap, limit); i64 num=600851475143LL; vector<i64> vresult; vresult = quadratic_sieve(num); for(unsigned int i = 0; i < vresult.size(); ++i) printf("%lld\n", vresult[i]); }
int main() { srand(1337); // The primes we will perform trial division with on small integers. std::vector<uint32_t> primes; // Generate the trial division primes using a simple sieve. { uint32_t max = (uint32_t)ceil(sqrt(TRIAL_BOUND)) + 1; char *sieve = new char[max]; memset(sieve, 1, max); for(uint32_t p = 2; p < max; ++p) { if(!sieve[p]) continue; primes.push_back(p); for(uint32_t i = p; i < max; i += p) sieve[i] = 0; } delete[] sieve; } mpz_class N; // Read numbers to factor from stdin until EOF. while(std::cin >> N) { // This quadratic sieve implementation is designed to factor numbers no larger than 100 bits. if(mpz_sizeinbase(N.get_mpz_t(), 2) > 100) { std::cerr << N << " is too large\n" << std::endl; continue; } std::stack<mpz_class> factors; factors.push(N); while(!factors.empty()) { mpz_class factor = factors.top(); factors.pop(); // If the factor is prime, print it. if(mpz_probab_prime_p(factor.get_mpz_t(), 10)) { std::cout << factor << std::endl; continue; // Run trial division if factor is small. } else if(factor < TRIAL_BOUND) { uint32_t f = factor.get_ui(); for(uint32_t p = 0; p < primes.size(); ++p) { if(f % primes[p] == 0) { factors.push(primes[p]); factors.push(factor / primes[p]); break; } } } else { // Before we run quadratic sieve, check for small factors. bool found_factor = false; for(uint32_t p = 0; p < primes.size(); ++p) { if(mpz_divisible_ui_p(factor.get_mpz_t(), primes[p])) { factors.push(primes[p]); factors.push(factor / primes[p]); found_factor = true; break; } } if(found_factor) continue; // Quadratic sieve doesn't handle perferct powers very well, handle those separately. if(mpz_perfect_power_p(factor.get_mpz_t())) { mpz_class root, rem; // Check root remainders up half of the amount of bits in factor. uint32_t max = mpz_sizeinbase(factor.get_mpz_t(), 2) / 2; for(uint32_t n = 2; n < max; ++n) { mpz_rootrem(root.get_mpz_t(), rem.get_mpz_t(), factor.get_mpz_t(), n); if(rem == 0) { // Push the n root factors. for(uint32_t i = 0; i < n; ++i) factors.push(root); break; } } } else { mpz_class f = quadratic_sieve(factor); factors.push(f); factors.push(factor / f); } } } std::cout << std::endl; } return 0; }