9 BigInt residue = base % mod;
10 if (residue.is_negative()) {
16 result = (result * residue) % mod;
18 residue = (residue * residue) % mod;
26BigInt BigInt::multinomial(
unsigned int n,
const std::vector<unsigned int>&
r) {
28 if (
r.empty())
return BigInt(1);
30 std::vector<uint> r_uints;
31 r_uints.reserve(
r.size());
34 r_uints.push_back((uint)val);
37 if (sum != n)
throw std::invalid_argument(
"multinomial: sum of ranks must equal n");
42 mp_size_t needed = lmmp_multinomial_size_(r_uints.data(), (uint)r_uints.size(), &n_calc);
44 res.realloc_to(needed);
45 res.size_ = lmmp_multinomial_(res.data_, needed, (uint)sum, r_uints.data(), (uint)r_uints.size());
51BigInt BigInt::gcd(
const BigInt&
a,
const BigInt&
b) {
53 if (
a.is_zero())
return b.abs();
54 if (
b.is_zero())
return a.abs();
56 BigInt abs_a =
a.abs();
57 BigInt abs_b =
b.abs();
60 mp_size_t na = abs_a.size_;
61 mp_size_t nb = abs_b.size_;
63 mp_size_t min_n = (na < nb) ? na : nb;
64 res.realloc_to(min_n);
66 res.size_ = lmmp_gcd_lehmer_(res.data_, abs_a.data_, na, abs_b.data_, nb);
73BigInt BigInt::lcm(
const BigInt&
a,
const BigInt&
b) {
74 if (
a.is_zero() ||
b.is_zero())
return BigInt(0);
75 return (
a.abs() / gcd(
a,
b)) *
b.abs();
78BigInt BigInt::pow_mod(
const BigInt& base,
const BigInt&
exp,
const BigInt& mod) {
80 if (
exp.is_negative()) {
81 throw std::domain_error(
82 "Negative exponent in modular integer power");
84 if (mod.is_zero() || mod.is_negative()) {
85 throw std::domain_error(
86 "Modulus must be positive in modular integer power");
88 if (mod == BigInt(1))
return BigInt(0);
90 if (base.size_ <= 1 &&
exp.size_ <= 1 && mod.size_ <= 1) {
91 const ulong modulus = mod.data_[0];
92 ulong residue = base.is_zero() ? 0 : base.data_[0] % modulus;
94 if (base.is_negative() && residue != 0) {
95 residue = modulus - residue;
97 if ((modulus & 1U) != 0) {
99 lmmp_powmod_ulong_odd_(residue,
exponent, modulus));
108 if (sign_ == NEGATIVE)
return false;
111 return lmmp_is_prime_ulong_(size_ == 0 ? 0 : data_[0]);
113 if (is_even())
return false;
115 static const uint64_t small_primes[] = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
116 for (
auto p : small_primes) {
117 if ((*
this % p).
is_zero())
return false;
120 const BigInt& n = *
this;
121 const BigInt n_minus_one = n - 1;
122 BigInt d = n_minus_one;
125 while (d.is_even()) {
130 static const uint64_t mr_bases[] = {2, 3, 5, 7, 11, 13, 17};
131 for (
auto base : mr_bases) {
132 BigInt x = BigInt::pow_mod(BigInt(base), d, n);
133 if (x == 1 || x == n_minus_one)
continue;
135 bool composite =
true;
136 for (
int r = 1;
r < s; ++
r) {
137 x = BigInt::pow_mod(x, two, n);
138 if (x == n_minus_one) {
143 if (composite)
return false;
147 "BigInt::is_prime_checked");
150bool BigInt::is_perfect_square()
const {
151 if (sign_ == NEGATIVE)
return false;
152 if (size_ == 0)
return true;
153 BigInt s = this->
sqrt();
154 return (s * s) == *
this;
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
static Result failure(CasErrc code, std::string message, std::string operation={})
BigInt binary_modular_power(const BigInt &base, const BigInt &exp, const BigInt &mod)
bool is_zero(const SymbolicExpr &expression)
void ensure_lmmc_lifecycle() noexcept
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
ExprResult sqrt(const ExprPtr &expression, ComputationContext &context)