6void bigint_mul(mp_ptr destination, mp_srcptr lhs, mp_size_t lhs_size,
7 mp_srcptr
rhs, mp_size_t rhs_size) {
9 ::lmmp_mul_(destination, lhs, lhs_size,
rhs, rhs_size);
11void bigint_div(mp_ptr quotient, mp_ptr remainder, mp_srcptr numerator,
13 mp_size_t denominator_size) {
15 ::lmmp_div_(quotient, remainder, numerator, numerator_size,
denominator,
20void BigInt::add_abs(BigInt& dst,
const BigInt&
a,
const BigInt&
b) {
21 mp_size_t n = std::max(
a.size_,
b.size_);
22 dst.realloc_to(n + 1);
26 mp_srcptr ap =
a.data_;
27 mp_srcptr bp =
b.data_;
28 mp_size_t na =
a.size_;
29 mp_size_t nb =
b.size_;
31 if (na < nb) { std::swap(ap, bp); std::swap(na, nb); }
34 cy = lmmp_add_n_(dst.data_, ap, bp, nb);
38 if (dst.data_ != ap) std::memcpy(dst.data_ + nb, ap + nb, (na - nb) *
sizeof(mp_limb_t));
41 while (cy && k < na) {
43 cy = (dst.data_[k] == 0);
52void BigInt::sub_abs(BigInt& dst,
const BigInt&
a,
const BigInt&
b) {
53 mp_size_t na =
a.size_;
54 mp_size_t nb =
b.size_;
59 bw = lmmp_sub_n_(dst.data_,
a.data_,
b.data_, nb);
62 if (dst.data_ !=
a.data_) std::memcpy(dst.data_ + nb,
a.data_ + nb, (na - nb) *
sizeof(mp_limb_t));
64 while (bw && k < na) {
66 bw = (dst.data_[k] == (mp_limb_t)-1);
74BigInt BigInt::operator+(
const BigInt& other)
const {
75 if (sign_ == ZERO)
return other;
76 if (other.sign_ == ZERO)
return *
this;
79 if (sign_ == other.sign_) {
80 add_abs(res, *
this, other);
84 int cmp = cmp_abs(*
this, other);
89 sub_abs(res, *
this, other);
92 sub_abs(res, other, *
this);
93 res.sign_ = other.sign_;
99BigInt BigInt::operator-(
const BigInt& other)
const {
100 return *
this + (-other);
103BigInt BigInt::operator*(
const BigInt& other)
const {
104 if (size_ == 0 || other.size_ == 0)
return BigInt(0);
107 mp_size_t na = size_;
108 mp_size_t nb = other.size_;
109 res.realloc_to(na + nb);
112 bigint_mul(res.data_, data_, na, other.data_, nb);
114 bigint_mul(res.data_, other.data_, nb, data_, na);
118 res.sign_ = (sign_ == other.sign_) ? POSITIVE : NEGATIVE;
123BigInt BigInt::operator/(
const BigInt& other)
const {
124 if (other.size_ == 0)
throw std::domain_error(
"Division by zero");
125 if (size_ < other.size_)
return BigInt(0);
128 mp_size_t na = size_;
129 mp_size_t nb = other.size_;
131 q.realloc_to(na - nb + 1);
134 bigint_div(q.data_,
r.data_, data_, na, other.data_, nb);
136 q.size_ = na - nb + 1;
137 q.sign_ = (sign_ == other.sign_) ? POSITIVE : NEGATIVE;
142BigInt BigInt::operator%(
const BigInt& other)
const {
143 if (other.size_ == 0)
throw std::domain_error(
"Division by zero");
144 if (size_ < other.size_)
return *
this;
147 mp_size_t na = size_;
148 mp_size_t nb = other.size_;
149 q.realloc_to(na - nb + 1);
154 bigint_div(q.data_,
r.data_, data_, na, other.data_, nb);
162BigInt& BigInt::operator+=(
const BigInt& other) { *
this = *
this + other;
return *
this; }
164BigInt& BigInt::operator-=(
const BigInt& other) { *
this = *
this - other;
return *
this; }
166BigInt& BigInt::operator*=(
const BigInt& other) { *
this = *
this * other;
return *
this; }
168BigInt& BigInt::operator/=(
const BigInt& other) { *
this = *
this / other;
return *
this; }
170BigInt& BigInt::operator%=(
const BigInt& other) { *
this = *
this % other;
return *
this; }
172BigInt BigInt::power(
unsigned long exp)
const {
174 if (
exp == 0)
return BigInt(1);
175 if (size_ == 0)
return BigInt(0);
178 mp_size_t needed = lmmp_pow_size_(data_, size_,
exp);
179 res.realloc_to(needed);
181 res.size_ = lmmp_pow_(res.data_, needed, data_, size_,
exp);
183 if (sign_ == NEGATIVE && (
exp & 1)) {
184 res.sign_ = NEGATIVE;
186 res.sign_ = POSITIVE;
192BigInt BigInt::power(BigInt
exp)
const {
193 if (
exp.sign_ == NEGATIVE)
throw std::domain_error(
"Negative exponent in integer power");
194 if (
exp.size_ == 0)
return BigInt(1);
196 if (
exp.size_ <= 1) {
197 mp_limb_t lo = (
exp.size_ == 0) ? 0 :
exp.data_[0];
198 if (lo <=
static_cast<mp_limb_t
>(std::numeric_limits<unsigned long>::max())) {
199 return power(
static_cast<unsigned long>(lo));
206 while (!
exp.is_zero()) {
207 if (
exp.data_[0] & 1) {
213 for (mp_size_t i =
exp.size_; i > 0; --i) {
214 mp_limb_t cur =
exp.data_[i-1];
215 mp_limb_t next_carry = cur & 1;
216 exp.data_[i-1] = (cur >> 1) | (carry << (LIMB_BITS - 1));
224BigInt BigInt::sqrt()
const {
226 if (sign_ == NEGATIVE)
throw std::domain_error(
"Sqrt of negative number");
227 if (size_ == 0)
return BigInt(0);
228 if (*
this == BigInt(1))
return BigInt(1);
232 const mp_size_t root_size = (size_ + 1) / 2;
233 res.realloc_to(root_size + 1);
235 lmmp_sqrt_(res.data_,
nullptr, data_, size_, 0);
237 res.size_ = root_size;
238 res.sign_ = POSITIVE;
244bool BigInt::is_odd()
const {
245 if (size_ == 0)
return false;
246 return (data_[0] & 1);
249bool BigInt::is_even()
const {
253mp_size_t BigInt::trailing_zeros()
const {
257 for (mp_size_t i = 0; i < size_; ++i) {
261 count += lmmp_tailing_zeros_(data_[i]);
268BigInt& BigInt::operator>>=(mp_size_t shift) {
270 if (shift == 0)
return *
this;
273 mp_size_t limb_shift = shift / LIMB_BITS;
274 mp_size_t bit_shift = shift % LIMB_BITS;
276 if (limb_shift >= size_) {
281 if (limb_shift > 0) {
282 std::memmove(data_, data_ + limb_shift, (size_ - limb_shift) *
sizeof(mp_limb_t));
287 lmmp_shr_(data_, data_, size_, bit_shift);
288 if (size_ > 0 && data_[size_-1] == 0) size_--;
294BigInt& BigInt::operator<<=(mp_size_t shift) {
295 if (shift == 0)
return *
this;
298 mp_size_t limb_shift = shift / LIMB_BITS;
299 mp_size_t bit_shift = shift % LIMB_BITS;
301 mp_size_t old_size = size_;
302 mp_size_t needed = old_size + limb_shift + (bit_shift > 0 ? 1 : 0);
306 mp_limb_t carry = lmmp_shl_(data_ + limb_shift, data_, old_size, bit_shift);
308 data_[old_size + limb_shift] = carry;
309 size_ = old_size + limb_shift + 1;
311 size_ = old_size + limb_shift;
314 std::memmove(data_ + limb_shift, data_, old_size *
sizeof(mp_limb_t));
318 if (limb_shift > 0) {
319 std::memset(data_, 0, limb_shift *
sizeof(mp_limb_t));
326BigInt BigInt::operator>>(mp_size_t shift)
const {
332BigInt BigInt::operator<<(mp_size_t shift)
const {
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
void bigint_div(mp_ptr quotient, mp_ptr remainder, mp_srcptr numerator, mp_size_t numerator_size, mp_srcptr denominator, mp_size_t denominator_size)
void bigint_mul(mp_ptr destination, mp_srcptr lhs, mp_size_t lhs_size, mp_srcptr rhs, mp_size_t rhs_size)
bool is_zero(const SymbolicExpr &expression)
ExpressionResult normalize(const Node &value, ComputationContext &context)
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
const ExprPtr & denominator