File: api.cpp

package info (click to toggle)
primecount 8.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,640 kB
  • sloc: cpp: 21,835; ansic: 121; sh: 99; makefile: 89
file content (144 lines) | stat: -rw-r--r-- 3,898 bytes parent folder | download
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
134
135
136
137
138
139
140
141
142
143
144
///
/// @file   api.cpp
/// @brief  Test primecount's C++ API.
///
/// Copyright (C) 2025 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.hpp>
#include <primecount-internal.hpp>
#include <int128_t.hpp>

#include <stdint.h>
#include <iostream>
#include <cstdlib>

using namespace primecount;

void check(bool OK)
{
  std::cout << "   " << (OK ? "OK" : "ERROR") << "\n";
  if (!OK)
    std::exit(1);
}

int main()
{
  // Test 64-bit pi(-x)
  int64_t n = -1;
  int64_t res = pi(n);
  std::cout << "pi(" << n << ") = " << res;
  check(res == 0);

  n = -9223372036854775807ll;
  res = pi(n);
  std::cout << "pi(" << n << ") = " << res;
  check(res == 0);

  n = (int64_t) 1e10;
  res = pi(n);
  std::cout << "pi(" << n << ") = " << res;
  check(res == 455052511);

  pc_int128_t n128;
  n128.lo = (uint64_t) 1e9;
  n128.hi = 0;
  pc_int128_t res128 = pi(n128);
  std::cout << "pi(" << n128.lo << ") = " << res128.lo;
  check(res128.lo == 50847534 && res128.hi == 0);

  // Check x >= primecount max x of 10^31.
  // primecount must detect issue and throw an exception.
  try {
    std::cout << "pi(2^114) throws primecount_error: ";
    n128.lo = 0;
    n128.hi = 1ull << 50;
    n128 = pi(n128);
    std::cout << "  ERROR" << std::endl;
    if (n128.lo != 0 || n128.hi != 0)
      std::cout << "ERROR: this code path should be unreachable!" << std::endl;
    return 1;
  }
  catch(primecount_error&)
  {
    std::cout << "  OK" << std::endl;
  }

  n = 455052511;
  res = nth_prime(n);
  std::cout << "nth_prime(" << n << ") = " << res;
  check(res == 9999999967);

  n128.lo = (uint64_t) 1e9;
  n128.hi = 0;
  res128 = nth_prime(n128);
  std::cout << "nth_prime(" << n128.lo << ") = " << res128.lo;
  check(res128.lo == 22801763489 && res128.hi == 0);

  // Check n >= primecount max n of ~ 10^29.
  // primecount must detect issue and throw an exception.
  try {
    std::cout << "nth_prime(2^114) throws primecount_error: ";
    n128.lo = 0;
    n128.hi = 1ull << 50;
    n128 = nth_prime(n128);
    std::cout << "  ERROR" << std::endl;
    if (n128.lo != 0 || n128.hi != 0)
      std::cout << "ERROR: this code path should be unreachable!" << std::endl;
    return 1;
  }
  catch(primecount_error&)
  {
    std::cout << "  OK" << std::endl;
  }

  n = (int64_t) 1e12;
  int64_t a = 78498;
  res = phi(n, a);
  std::cout << "phi(" << n << ", " << a << ") = " << res;
  check(res == 37607833521);

  std::cout << "primecount version: " << primecount_version();
  check(primecount_version() == std::string(PRIMECOUNT_VERSION));

  std::cout << "threads: " << get_num_threads() << std::endl;

  // If multi-threading is disabled setting the
  // number of threads must have no effect.
  if (get_num_threads() <= 1)
  {
    set_num_threads(2);
    std::cout << "new threads: " << get_num_threads();
    check(get_num_threads() == 1);
  }
  else
  {
    set_num_threads(2);
    std::cout << "new threads: " << get_num_threads();
    check(get_num_threads() == 2);
  }

  std::pair<double, double> alphas1 = get_alpha_gourdon(1ull << 50);

  set_double_check(true);
  std::pair<double, double> alphas2 = get_alpha_gourdon(1ull << 50);
  std::cout << "set_double_check(true) alpha_y: " << alphas2.first;
  check(alphas2.first != alphas1.first);
  std::cout << "set_double_check(true) alpha_z: " << alphas2.second;
  check(alphas2.second != alphas1.second);

  set_double_check(false);
  std::pair<double, double> alphas3 = get_alpha_gourdon(1ull << 50);
  std::cout << "set_double_check(false) alpha_y: " << alphas3.first;
  check(alphas3.first == alphas1.first);
  std::cout << "set_double_check(false) alpha_z: " << alphas3.second;
  check(alphas3.second == alphas1.second);

  std::cout << std::endl;
  std::cout << "All tests passed successfully!" << std::endl;

  return 0;
}