Beispiel #1
0
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);
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}