1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
///
/// @file P2.cpp
/// @brief Test the 2nd partial sieve function P2(x, a)
/// that counts the numbers <= x that have exactly
/// 2 prime factors each exceeding the a-th prime.
///
/// Copyright (C) 2023 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///
#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <generate_primes.hpp>
#include <imath.hpp>
#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <random>
using std::size_t;
using namespace primecount;
void check(bool OK)
{
std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
if (!OK)
std::exit(1);
}
int main()
{
// Test small x values
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(2, 1000);
for (int i = 0; i < 100; i++)
{
int threads = 1;
int64_t x = dist(gen);
auto primes = generate_primes<int64_t>(x);
for (int a = 1; primes[a] <= isqrt(x); a++)
{
int64_t p2 = 0;
for (size_t b = a + 1; b < primes.size(); b++)
{
for (size_t c = b; c < primes.size(); c++)
{
if (primes[b] * primes[c] <= x)
p2++;
else
break;
}
}
std::cout << "P2(" << x << ", " << a << ") = " << p2;
check(p2 == P2(x, primes[a], a, threads));
}
}
}
// Test medium x values
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(1000, 200000);
for (int i = 0; i < 100; i++)
{
int threads = 1;
int64_t x = dist(gen);
auto primes = generate_primes<int64_t>(x);
for (int a = 1; primes[a] <= isqrt(x); a++)
{
int64_t p2 = 0;
for (size_t b = a + 1; b < primes.size(); b++)
{
for (size_t c = b; c < primes.size(); c++)
{
if (primes[b] * primes[c] <= x)
p2++;
else
break;
}
}
std::cout << "P2(" << x << ", " << a << ") = " << p2;
check(p2 == P2(x, primes[a], a, threads));
}
}
}
int threads = get_num_threads();
{
// Test P2(1e13) and compare with known correct value
int64_t x = 10000000000000ll;
int64_t y = 178815;
int64_t a = 16229;
int64_t res1 = P2(x, y, a, threads);
int64_t res2 = 113111712222ll;
std::cout << "P2(" << x << ", " << y << ", " << a << ") = " << res1;
check(res1 == res2);
}
#ifdef HAVE_INT128_T
{
// Test P2(1e14) and compare with known correct value
int128_t x = 100000000000000ll;
int64_t y = 494134;
int64_t a = 41080;
int128_t res1 = P2(x, y, a, threads);
int128_t res2 = 1026583290763ll;
std::cout << "P2(" << x << ", " << y << ", " << a << ") = " << res1;
check(res1 == res2);
}
#endif
std::cout << std::endl;
std::cout << "All tests passed successfully!" << std::endl;
return 0;
}
|