#include <primecount-internal.hpp>
#include <imath.hpp>
#include <stdint.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <vector>
using std::max;
using std::size_t;
using namespace primecount;
std::vector<int64_t> Li_table =
{
5, 29, 176, 1245, 9628, 78626, 664917, 5762208, 50849233, 455055613, 4118066399ll, 37607950279ll, 346065645809ll, 3204942065690ll, 29844571475286ll };
void check(bool OK)
{
std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
if (!OK)
std::exit(1);
}
int main()
{
for (size_t i = 0; i < Li_table.size(); i++)
{
int p = (int) i + 1;
int64_t x = ipow(10ll, p);
std::cout << "Li(" << x << ") = " << Li(x);
check(Li(x) == Li_table[i]);
}
for (size_t i = 0; i < Li_table.size(); i++)
{
int p = (int) i + 1;
int64_t x = ipow(10ll, p);
std::cout << "Li_inverse(" << Li_table[i] << ") = " << Li_inverse(Li_table[i]);
check(Li_inverse(Li_table[i]) <= x &&
Li_inverse(Li_table[i] + 1) > x);
}
for (int64_t x = 0; x < 300000; x++)
{
int64_t lix = Li(x);
double logx = std::log(max((double) x, 2.0));
if (lix < 0 ||
(x >= 11 && lix < x / logx) ||
(x >= 2 && lix > x * logx))
{
std::cout << "Li(" << x << ") = " << lix << " ERROR" << std::endl;
std::exit(1);
}
}
for (int64_t x = 2; x < 30000; x++)
{
int64_t res = Li_inverse(x);
double logx = std::log((double) x);
if (res < 0 ||
res < x ||
(x >= 4 && res > x * logx * logx))
{
std::cout << "Li_inverse(" << x << ") = " << res << " ERROR" << std::endl;
std::exit(1);
}
}
std::cout << std::endl;
std::cout << "All tests passed successfully!" << std::endl;
return 0;
}