TEST(GeneratorTest, Comparision) { primewheel pwg, pws; siever svr; sieve segment; new_primewheel(&pwg, 3); new_primewheel(&pws, 4); new_sieve(&segment, DEF_BUFSIZE, 0); new_siever(&svr, &pws, 1000); prime* ps; size_t pcount; segmented_list_primes(&svr, &segment, 0, GEN_LIM, &ps, &pcount); prime_generator pg; new_prime_generator(&pg, &pwg, 100); size_t pgcount = 0; for (prime p = prime_generator_next(&pg, &segment); p < GEN_LIM; p = prime_generator_next(&pg, &segment)) { if (pgcount < pcount) { ASSERT_EQ(ps[pgcount], p); } pgcount++; } ASSERT_EQ(pcount, pgcount); free_primewheel(&pwg); free_primewheel(&pws); free_prime_generator(&pg); free_sieve(&segment); free_siever(&svr); free(ps); }
/** * Returns 1 (true) if the specified number is a prime number, 0 (false) * otherwise. */ int is_prime(unsigned long num) { unsigned int *sieve; char num_bit; unsigned long start_pos, i, ptr_size; ldiv_t qr; /* Edge cases */ if ((num == 0) || (num == 1)) return 0; /* The sieve we'll use to determine if num is a prime or not. */ sieve = new_sieve(num); ptr_size = sizeof(sieve[0])*CHAR_BIT; /* sieve[2] represents the number 2. We only have to find multiples/factors up to sqrt(num). */ for (start_pos = 2; start_pos <= (unsigned long)sqrt(num); ++start_pos) { /* If this number is cleared, then so will all of its multiples, in which case there is nothing needed to be done. */ qr = ldiv(start_pos, ptr_size); if (( sieve[qr.quot] & (1 << qr.rem) ) != 0) { /* Clear all numbers that are multiples of 'sieve[start_pos]' */ for (i = start_pos; i <= num; i = i + start_pos) { qr = ldiv(i, ptr_size); sieve[qr.quot] &= ~(1 << qr.rem); if (i == num) { /* We've cleared 'sieve[num]' we now know it's not a prime number */ break; } } if (i == num) { printf("Divisible by %lu\n", start_pos); /* We've cleared 'sieve[num]' we now know it's not a prime number */ break; } } } /* Get the value of the bit at position 'num' */ qr = ldiv(num, ptr_size); num_bit = ( sieve[qr.quot] & (1 << qr.rem) ) != 0; free(sieve); // 'num' is a prime if the bit 'sieve[num]' was still set. return num_bit; }
TEST(SegmentedSieveTest, BasicCount) { primewheel pw; new_primewheel(&pw, 4); siever svr; new_siever(&svr, &pw, 1e9); sieve segment; new_sieve(&segment, DEF_BUFSIZE, 0); for (size_t i = 0; i < sizeof(P_COUNTS) / sizeof(P_COUNTS[0]); i++) { ASSERT_EQ(P_COUNTS[i], segmented_count_primes(&svr, &segment, 0, P_LIMITS[i])); } free_sieve(&segment); free_siever(&svr); free_primewheel(&pw); }
TEST(SegmentedSieveTest, List) { primewheel pw; new_primewheel(&pw, 4); siever svr; new_siever(&svr, &pw, 1e9); sieve segment; new_sieve(&segment, DEF_BUFSIZE, 0); prime* primes; size_t nprimes = 1; segmented_list_primes(&svr, &segment, 0, P_LIMITS[7], &primes, &nprimes); ASSERT_EQ(P_COUNTS[7], nprimes); ASSERT_EQ(17329489, primes[1111110]); free(primes); free_sieve(&segment); free_siever(&svr); free_primewheel(&pw); }
TEST(SegmentedSieveTest, SubtractCount) { primewheel pw; new_primewheel(&pw, 4); siever svr; new_siever(&svr, &pw, 1e9); sieve segment; new_sieve(&segment, DEF_BUFSIZE, 0); size_t ncounts = sizeof(P_COUNTS) / sizeof(P_COUNTS[0]); size_t large_count = segmented_count_primes(&svr, &segment, 0, P_LIMITS[ncounts - 1]); for (size_t i = 0; i < ncounts - 1; i++) { ASSERT_EQ(large_count - P_COUNTS[i], segmented_count_primes(&svr, &segment, P_LIMITS[i], P_LIMITS[ncounts - 1])) << "failed limit: P_LIMITS[" << i << "] = " << std::scientific << (double)P_LIMITS[i]; } free_sieve(&segment); free_siever(&svr); free_primewheel(&pw); }
TEST(SegmentedSieveTest, TrivialCasese) { primewheel pw; new_primewheel(&pw, 4); siever siever; new_siever(&siever, &pw, 1e7); sieve segment; new_sieve(&segment, DEF_BUFSIZE, 0); ASSERT_EQ(0, segmented_count_primes(&siever, &segment, 0, 0)); ASSERT_EQ(0, segmented_count_primes(&siever, &segment, 0, 1)); ASSERT_EQ(0, segmented_count_primes(&siever, &segment, 100, 99)); prime *primes; size_t pcount; segmented_list_primes(&siever, &segment, 0, 0, &primes, &pcount); ASSERT_EQ(0, pcount); free(primes); segmented_list_primes(&siever, &segment, 0, 1, &primes, &pcount); ASSERT_EQ(0, pcount); free(primes); segmented_list_primes(&siever, &segment, 100, 99, &primes, &pcount); ASSERT_EQ(0, pcount); free(primes); free_siever(&siever); free_primewheel(&pw); free_sieve(&segment); }
TEST(SegmentedSieveTest, ExtendSiever) { primewheel pw; new_primewheel(&pw, 4); siever svr1, svr2; new_siever(&svr1, &pw, 1e7); new_siever(&svr2, &pw, 1e9); sieve segment; new_sieve(&segment, DEF_BUFSIZE, 0); extend_siever(&svr1, &segment, 1e9); ASSERT_EQ(svr2.n_sieving_primes, svr1.n_sieving_primes); for (size_t i = 0; i < svr2.n_sieving_primes; i++) { sieving_prime *svp1, *svp2; svp1 = svr1.sieving_primes[i]; svp2 = svr2.sieving_primes[i]; ASSERT_EQ(svp2->prime, svp1->prime); ASSERT_EQ(svp2->offset, svp1->offset); } free_siever(&svr1); free_siever(&svr2); free_primewheel(&pw); }