#include <primecount-internal.hpp>
#include <imath.hpp>
#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <vector>
using std::max;
using std::size_t;
using namespace primecount;
std::vector<int64_t> Ri_table =
{
4, 25, 168, 1226, 9587, 78527, 664667, 5761551, 50847455, 455050683, 4118052494ll, 37607910542ll, 346065531065ll, 3204941731601ll };
void check(bool OK)
{
std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
if (!OK)
std::exit(1);
}
int main()
{
for (size_t i = 0; i < Ri_table.size(); i++)
{
int p = (int) i + 1;
int64_t x = ipow(10ll, p);
std::cout << "Ri(" << x << ") = " << Ri(x);
check(Ri(x) == Ri_table[i]);
}
for (size_t i = 0; i < Ri_table.size(); i++)
{
int p = (int) i + 1;
int64_t x = ipow(10ll, p);
std::cout << "Ri_inverse(" << Ri_table[i] << ") = " << Ri_inverse(Ri_table[i]);
check(Ri_inverse(Ri_table[i]) < x &&
Ri_inverse(Ri_table[i] + 1) >= x);
}
int64_t x;
for (x = 0; x < 10000; x++)
{
int64_t rix = Ri(x);
double logx = std::log(max((double) x, 2.0));
if (rix < 0 ||
(x >= 20 && rix < x / logx) ||
(x >= 2 && rix > x * logx))
{
std::cout << "Ri(" << x << ") = " << rix << " ERROR" << std::endl;
std::exit(1);
}
}
for (; x < 100000; x += 101)
{
int64_t rix = Ri(x);
double logx = std::log(max((double) x, 2.0));
if (rix < 0 ||
(x >= 20 && rix < x / logx) ||
(x >= 2 && rix > x * logx))
{
std::cout << "Ri(" << x << ") = " << rix << " ERROR" << std::endl;
std::exit(1);
}
}
for (x = 2; x < 1000; x++)
{
int64_t res = Ri_inverse(x);
double logx = std::log((double) x);
if (res < 0 ||
res < x ||
(x >= 5 && res > x * logx * logx))
{
std::cout << "Ri_inverse(" << x << ") = " << res << " ERROR" << std::endl;
std::exit(1);
}
}
for (; x < 100000; x += 101)
{
int64_t res = Ri_inverse(x);
double logx = std::log((double) x);
if (res < 0 ||
res < x ||
(x >= 5 && res > x * logx * logx))
{
std::cout << "Ri_inverse(" << x << ") = " << res << " ERROR" << std::endl;
std::exit(1);
}
}
std::cout << std::endl;
std::cout << "All tests passed successfully!" << std::endl;
return 0;
}