17 constexpr
size_t prime_add_mod(
size_t a,
size_t b,
size_t nModulus) noexcept
19 return a >= nModulus - b ? a - (nModulus - b) : a + b;
22 constexpr
size_t prime_multiply_mod(
size_t a,
size_t b,
size_t nModulus) noexcept
28 nResult = prime_add_mod(nResult, a, nModulus);
30 a = prime_add_mod(a, a, nModulus);
35 constexpr
size_t prime_power_mod(
size_t nBase,
size_t nExponent,
size_t nModulus) noexcept
39 while (nExponent != 0)
42 nResult = prime_multiply_mod(nResult, nBase, nModulus);
44 nBase = prime_multiply_mod(nBase, nBase, nModulus);
54 static_assert(std::is_integral_v<I>,
"Integral required");
56 std::vector<I> factors;
58 bool bValueNegative =
false;
59 if constexpr (std::numeric_limits<I>::min() < 0)
63 bValueNegative =
true;
70 while (nValue % 2 == 0)
77 I nMaxFactor =
static_cast<I
>(std::sqrt(nValue));
78 while (i <= nMaxFactor)
80 while (nValue % i == 0)
84 nMaxFactor =
static_cast<I
>(std::sqrt(nValue));
91 factors.push_back(nValue);
94 if constexpr (std::numeric_limits<I>::min() < 0)
95 if (!factors.empty() && bValueNegative)
96 factors[0] = -factors[0];
104 static_assert(std::is_integral_v<I>,
"Integral required");
106 std::vector<bool> isComposite(
static_cast<size_t>(nMaxNumber) + 1,
false);
108 constexpr
size_t first_composite_power_of_two = 4;
109 for (
size_t i = first_composite_power_of_two; i < static_cast<size_t>(nMaxNumber) + 1; i += 2)
111 isComposite[i] =
true;
115 I nStopAt =
static_cast<I
>(std::sqrt(nMaxNumber + 1));
116 while (nNextPrime <= nStopAt)
118 for (I i = nNextPrime * 2; i < nMaxNumber + 1; i += nNextPrime)
119 isComposite[
static_cast<size_t>(i)] =
true;
123 while (nNextPrime <= nMaxNumber && isComposite[
static_cast<size_t>(nNextPrime)])
129 std::vector<I> primes;
130 primes.reserve(
static_cast<size_t>(nMaxNumber / 2));
132 for (I i = 2; i < nMaxNumber + 1; ++i)
133 if (!isComposite[
static_cast<size_t>(i)])
136 primes.shrink_to_fit();
145 inline bool is_prime(
size_t nValue,
double fProbability)
147 if (fProbability < 0)
148 fProbability = -fProbability;
150 if (fProbability >= 1 || std::fabs(fProbability) <= DBL_EPSILON)
153 constexpr
double fLog2 = 0.30102999566;
155 const double fTests = std::ceil(std::log(1.0 / (1.0 - fProbability)) / fLog2);
157 std::default_random_engine generator(
static_cast<unsigned>(std::time(
nullptr)));
159 std::uniform_int_distribution<size_t> num_dist(2, nValue);
161 for (
unsigned i = 0; i < fTests; ++i)
163 const size_t nRandomNumber = num_dist(generator);
164 if (details::prime_power_mod(nRandomNumber, nValue - 1, nValue) != 1)
std::vector< I > find_primes(I nMaxNumber)
Find all primes between 2 and nMaxNumber.
bool is_prime(size_t nValue)
Is number prime.
std::vector< I > find_prime_factors(I nValue)
Find all prime factors.