/// /// @file Ri.cpp /// @brief Test the Riemann R function. /// /// Copyright (C) 2021 Kim Walisch, /// /// This file is distributed under the BSD License. See the COPYING /// file in the top level directory. /// #include #include #include #include #include #include using std::max; using std::size_t; using namespace primecount; std::vector 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; }