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
|
///
/// @file Ri.cpp
/// @brief Test the Riemann R function.
///
/// Copyright (C) 2021 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-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, // Ri(10^1)
25, // Ri(10^2)
168, // Ri(10^3)
1226, // Ri(10^4)
9587, // Ri(10^5)
78527, // Ri(10^6)
664667, // Ri(10^7)
5761551, // Ri(10^8)
50847455, // Ri(10^9)
455050683, // Ri(10^10)
4118052494ll, // Ri(10^11)
37607910542ll, // Ri(10^12)
346065531065ll, // Ri(10^13)
3204941731601ll // Ri(10^14)
};
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;
// Sanity checks for tiny values of Ri(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);
}
}
// Sanity checks for small values of Ri(x)
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);
}
}
// Sanity checks for tiny values of Ri_inverse(x)
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);
}
}
// Sanity checks for small values of Ri_inverse(x)
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;
}
|