#include <imath.hpp>
#include <int128_t.hpp>
#include <stdint.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace primecount;
void check(bool OK)
{
std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
if (!OK)
std::exit(1);
}
int main()
{
uint64_t n;
uint64_t res1;
double res2;
if (sizeof(long double) > 8)
{
for (n = 0; n < 100000; n++)
{
res1 = iroot<2>(n);
res2 = std::sqrt((long double) n);
std::cout << "iroot<2>(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);
}
for (n = 0; n < 100000; n++)
{
res1 = iroot<3>(n);
res2 = std::cbrt((long double) n);
std::cout << "iroot<3>(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);
}
for (n = 0; n < 100000; n++)
{
res1 = iroot<4>(n);
res2 = std::pow((long double) n, 1.0L / 4);
std::cout << "iroot<4>(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);
}
for (n = 0; n < 100000; n++)
{
res1 = iroot<6>(n);
res2 = std::pow((long double) n, 1.0L / 6);
std::cout << "iroot<6>(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);
}
}
n = 18446744073709551615ull;
res1 = iroot<2>(n);
std::cout << "iroot<2>(" << n << ") = " << res1;
check(res1 == 4294967295ull);
n = 18446744073709551615ull;
res1 = iroot<3>(n);
std::cout << "iroot<3>(" << n << ") = " << res1;
check(res1 == 2642245);
for (uint64_t i = 2000000; i <= 2100000; i++)
{
n = ipow(i, 3);
res1 = iroot<3>(n);
std::cout << "iroot<3>(" << n << ") = " << res1;
check(res1 == i);
res1 = iroot<3>(n - 1);
std::cout << "iroot<3>(" << n - 1 << ") = " << res1;
check(res1 == i - 1);
}
n = 18446744073709551615ull;
res1 = iroot<4>(n);
std::cout << "iroot<4>(" << n << ") = " << res1;
check(res1 == 65535);
n = 18446744073709551615ull;
res1 = iroot<6>(n);
std::cout << "iroot<6>(" << n << ") = " << res1;
check(res1 == 1625);
for (uint64_t i = 1; i <= 1625; i++)
{
n = ipow(i, 6);
res1 = iroot<6>(n);
std::cout << "iroot<6>(" << n << ") = " << res1;
check(res1 == i);
res1 = iroot<6>(n - 1);
std::cout << "iroot<6>(" << n - 1 << ") = " << res1;
check(res1 == i - 1);
}
#ifdef HAVE_INT128_T
int128_t m;
int128_t res;
if (sizeof(long double) > 8)
{
for (m = 0; m < 100000; m++)
{
res = iroot<2>(m);
res2 = std::sqrt((long double) m);
std::cout << "iroot<2>(" << m << ") = " << res;
check(res == (int128_t) res2);
}
for (m = 0; m < 100000; m++)
{
res = iroot<3>(m);
res2 = std::cbrt((long double) m);
std::cout << "iroot<3>(" << m << ") = " << res;
check(res == (int128_t) res2);
}
for (m = 0; m < 100000; m++)
{
res = iroot<4>(m);
res2 = std::pow((long double) m, 1.0L / 4);
std::cout << "iroot<4>(" << m << ") = " << res;
check(res == (int128_t) res2);
}
for (m = 0; m < 100000; m++)
{
res = iroot<6>(m);
res2 = std::pow((long double) m, 1.0L / 6);
std::cout << "iroot<6>(" << m << ") = " << res;
check(res == (int128_t) res2);
}
}
m = ipow((int128_t) 10, 30);
res = iroot<2>(m);
std::cout << "iroot<2>(" << m << ") = " << res;
check(res == ipow(10ll, 15));
res = iroot<2>(m - 1);
std::cout << "iroot<2>(" << m - 1 << ") = " << res;
check(res == ipow(10ll, 15) - 1);
res = iroot<3>(m);
std::cout << "iroot<3>(" << m << ") = " << res;
check(res == ipow(10ll, 10));
res = iroot<3>(m - 1);
std::cout << "iroot<3>(" << m - 1 << ") = " << res;
check(res == ipow(10ll, 10) - 1);
res = iroot<6>(m);
std::cout << "iroot<6>(" << m << ") = " << res;
check(res == ipow(10, 5));
res = iroot<6>(m - 1);
std::cout << "iroot<6>(" << m - 1 << ") = " << res;
check(res == ipow(10, 5) - 1);
m = ipow((int128_t) 10, 28);
res = iroot<4>(m);
std::cout << "iroot<4>(" << m << ") = " << res;
check(res == ipow(10ll, 7));
res = iroot<4>(m - 1);
std::cout << "iroot<4>(" << m - 1 << ") = " << res;
check(res == ipow(10ll, 7) - 1);
#endif
std::cout << std::endl;
std::cout << "All tests passed successfully!" << std::endl;
return 0;
}