LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
divexact.c 文件参考
+ divexact.c 的引用(Include)关系图:

浏览源代码.

宏定义

#define c   (tp)
 
#define l   (tp + dn)
 
#define scratch   (tp + 2 * dn)
 

函数

void lmmp_divexact_ (mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn)
 
void lmmp_divexact_1_ (mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_limb_t d, mp_limb_t dinv)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 
void lmmp_divexact_2_ (mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_srcptr restrict dp, mp_srcptr restrict dinv)
 
void lmmp_divexact_basecase_ (mp_ptr dst, mp_ptr np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn, mp_limb_t dinv)
 
void lmmp_divexact_divide_ (mp_ptr restrict dst, mp_srcptr restrict np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn)
 
void lmmp_divexact_unbalanced_ (mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn, mp_ptr restrict dinv)
 
static void lmmp_mulhi_n_ (mp_ptr dst, mp_srcptr restrict lop, mp_srcptr restrict numa, mp_srcptr restrict numb, mp_size_t n, mp_ptr tp)
 已知乘积的低位,计算乘积的高位
 
static void lmmp_mullo_n_ (mp_ptr restrict dst, mp_srcptr restrict numa, mp_srcptr restrict numb, mp_size_t n, mp_ptr restrict tp)
 

宏定义说明

◆ c

#define c   (tp)

◆ l

#define l   (tp + dn)

◆ scratch

#define scratch   (tp + 2 * dn)

函数说明

◆ lmmp_divexact_()

void lmmp_divexact_ ( mp_ptr  dst,
mp_srcptr  np,
mp_size_t  nn,
mp_srcptr restrict  dp,
mp_size_t  dn 
)

在文件 divexact.c273 行定义.

273 {
274 lmmp_param_assert(dst != NULL && np != NULL && dp != NULL);
276 lmmp_param_assert(nn >= dn);
277 lmmp_param_assert((dp[0] & 1) != 0);
278
279 if (dn == 1) {
281 lmmp_divexact_1_(dst, np, nn, dp[0], dinv);
282 } else if (dn == 2) {
283 mp_limb_t dinv[2];
285 lmmp_divexact_2_(dst, np, nn, dp, dinv);
286 } else {
287 mp_size_t qn = nn - dn + 1;
290 TEMP_DECL;
292 lmmp_copy(tp, np, nn);
294 TEMP_FREE;
295 } else if (qn < dn) {
296 TEMP_DECL;
298 if (dst == np) {
299 tp = TALLOC_TYPE(nn, mp_limb_t);
300 lmmp_copy(tp, np, nn);
301 np = tp;
302 }
303 lmmp_divexact_divide_(dst, np, nn, dp, dn);
304 TEMP_FREE;
305 } else {
307 }
308 }
309}
void lmmp_divexact_1_(mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_limb_t d, mp_limb_t dinv)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition divexact.c:24
void lmmp_divexact_divide_(mp_ptr restrict dst, mp_srcptr restrict np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn)
Definition divexact.c:243
void lmmp_divexact_2_(mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_srcptr restrict dp, mp_srcptr restrict dinv)
Definition divexact.c:49
void lmmp_divexact_unbalanced_(mp_ptr dst, mp_srcptr np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn, mp_ptr restrict dinv)
Definition divexact.c:160
void lmmp_divexact_basecase_(mp_ptr dst, mp_ptr np, mp_size_t nn, mp_srcptr restrict dp, mp_size_t dn, mp_limb_t dinv)
Definition divexact.c:214
mp_limb_t * mp_ptr
Definition lmmp.h:80
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
uint64_t mp_size_t
Definition lmmp.h:77
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_param_assert(x)
Definition lmmp.h:401
#define DIVEXACT_NN_THRESHOLD
Definition mparam.h:126
#define DIVEXACT_BASECASE_THRESHOLD
Definition mparam.h:124
#define tp
#define n
ulong lmmp_binvert_ulong_(ulong a)
计算 a 在2^64下的逆元
Definition binvert_1.c:42
void lmmp_binvert_2_(mp_ptr dst, mp_srcptr numa)
计算 [numa,2] 在 B^2 下的逆元
Definition binvert_1.c:56
#define TEMP_DECL
Definition tmp_alloc.h:131
#define TEMP_FREE
Definition tmp_alloc.h:150
#define TALLOC_TYPE(n, type)
Definition tmp_alloc.h:148

引用了 DIVEXACT_BASECASE_THRESHOLD, DIVEXACT_NN_THRESHOLD, lmmp_binvert_2_(), lmmp_binvert_ulong_(), lmmp_copy, lmmp_divexact_1_(), lmmp_divexact_2_(), lmmp_divexact_basecase_(), lmmp_divexact_divide_(), lmmp_divexact_unbalanced_(), lmmp_param_assert, n, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

+ 函数调用图:

◆ lmmp_divexact_1_()

void lmmp_divexact_1_ ( mp_ptr  dst,
mp_srcptr  np,
mp_size_t  nn,
mp_limb_t  d,
mp_limb_t  dinv 
)

Copyright (C) 2026 HJimmyK(Jericho Knox)

精确除法([dst,nn]=[np,nn]/d,且余数必须为0)

This file is part of LAMMP.

LAMMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed WITHOUT ANY WARRANTY.

See https://www.gnu.org/licenses/.

在文件 divexact.c24 行定义.

24 {
25 lmmp_param_assert(d % 2 == 1);
26 lmmp_param_assert(dinv * d == 1);
27 lmmp_param_assert(nn > 0);
28 lmmp_debug_assert(dst != NULL && np != NULL);
29 mp_limb_t c = 0;
30 mp_limb_t l, s, lo, hi, q;
32 for (i = 0; i < nn - 1; i++) {
33 s = np[i];
34 l = s - c;
35 c = l > s;
36 q = l * dinv;
37 dst[i] = q;
38 _umul64to128_(q, d, &lo, &hi);
39 c += hi;
40 }
41 s = np[i];
42 l = s - c;
43 c = l > s;
44 q = l * dinv;
45 dst[i] = q;
46 lmmp_debug_assert(c == 0);
47}
#define l
#define c
#define lmmp_debug_assert(x)
Definition lmmp.h:390
static void _umul64to128_(uint64_t a, uint64_t b, uint64_t *low, uint64_t *high)
Definition longlong.h:174
#define s
#define lo

引用了 _umul64to128_(), c, l, lmmp_debug_assert, lmmp_param_assert, lo, n , 以及 s.

被这些函数引用 lmmp_divexact_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_divexact_2_()

void lmmp_divexact_2_ ( mp_ptr  dst,
mp_srcptr  np,
mp_size_t  nn,
mp_srcptr restrict  dp,
mp_srcptr restrict  dinv 
)

在文件 divexact.c49 行定义.

49 {
50 lmmp_param_assert(dp[0] % 2 == 1);
51 lmmp_param_assert(nn > 1);
52 lmmp_debug_assert(dst != NULL && np != NULL);
53 mp_limb_t c[2] = {0, 0};
54 mp_limb_t l[2], s[2], q[2], t[4];
56 mp_limb_t d0 = dp[0], d1 = dp[1];
57 mp_limb_t ddinv0 = dinv[0], ddinv1 = dinv[1];
58
59 if (nn % 2 == 0) {
60 for (i = 0; i < nn - 2; i += 2) {
61 s[0] = np[i];
62 s[1] = np[i + 1];
63 _u128sub(l, s, c);
64 c[0] = _u128cmp(s, l) ? 1 : 0;
65 c[1] = 0;
66 _umul128to128_(l[1], l[0], ddinv1, ddinv0, q);
67 dst[i] = q[0];
68 dst[i + 1] = q[1];
69 _umul128to256_(q[1], q[0], d1, d0, t);
70 _u128add(c, c, t + 2);
71 }
72 s[0] = np[i];
73 s[1] = np[i + 1];
74 _u128sub(l, s, c);
75 c[0] = _u128cmp(s, l);
76 _umul128to128_(l[1], l[0], ddinv1, ddinv0, q);
77 dst[i] = q[0];
78 lmmp_debug_assert(c[0] == 0);
79 } else {
80 i = 0;
81 if (nn >= 5) {
82 for (; i < nn - 4; i += 2) {
83 s[0] = np[i];
84 s[1] = np[i + 1];
85 _u128sub(l, s, c);
86 c[0] = _u128cmp(s, l);
87 c[1] = 0;
88 _umul128to128_(l[1], l[0], ddinv1, ddinv0, q);
89 dst[i] = q[0];
90 dst[i + 1] = q[1];
91 _umul128to256_(q[1], q[0], d1, d0, t);
92 _u128add(c, c, t + 2);
93 }
94 }
95 s[0] = np[i];
96 s[1] = np[i + 1];
97 _u128sub(l, s, c);
98 c[0] = _u128cmp(s, l);
99 _umul128to128_(l[1], l[0], ddinv1, ddinv0, q);
100 dst[i] = q[0];
101 dst[i + 1] = q[1];
102 lmmp_debug_assert(c[0] == 0);
103 }
104}
#define _u128add(r, x, y)
Definition longlong.h:346
static void _umul128to256_(uint64_t a_high, uint64_t a_low, uint64_t b_high, uint64_t b_low, uint64_t rr[4])
Definition longlong.h:212
#define _u128sub(r, x, y)
Definition longlong.h:368
#define _u128cmp(x, y)
Definition longlong.h:366
static void _umul128to128_(uint64_t a_high, uint64_t a_low, uint64_t b_high, uint64_t b_low, uint64_t rr[2])
Definition longlong.h:241
#define t

引用了 _u128add, _u128cmp, _u128sub, _umul128to128_(), _umul128to256_(), c, l, lmmp_debug_assert, lmmp_param_assert, n, s , 以及 t.

被这些函数引用 lmmp_divexact_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_divexact_basecase_()

void lmmp_divexact_basecase_ ( mp_ptr  dst,
mp_ptr  np,
mp_size_t  nn,
mp_srcptr restrict  dp,
mp_size_t  dn,
mp_limb_t  dinv 
)

在文件 divexact.c214 行定义.

214 {
215 lmmp_param_assert(dst != NULL && np != NULL && dp != NULL);
217 lmmp_param_assert(nn >= dn);
218 lmmp_param_assert((dp[0] & 1) != 0);
219 lmmp_param_assert((dp[0] * dinv) == 1);
220 mp_size_t i;
221 mp_limb_t q;
223 mp_size_t qn = nn - dn + 1;
224 for (i = 0; i < qn; i++) {
225 q = dinv * np[i];
226 hi = lmmp_submul_1_(np + i, dp, dn, q);
227 lmmp_debug_assert(np[i] == 0);
228#if LAMMP_DEBUG_ASSERT_CHECK == 1
229 if (hi && i + dn < nn) {
230 lmmp_dec_1(np + i + dn, hi);
231 } else {
232 lmmp_debug_assert(hi == 0);
233 }
234#else
235 if (hi) {
236 lmmp_dec_1(np + i + dn, hi);
237 }
238#endif
239 dst[i] = q;
240 }
241}
#define lmmp_dec_1(p, dec)
大数减指定值宏(预期无借位)
Definition lmmpn.h:977
mp_limb_t lmmp_submul_1_(mp_ptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t b)
大数乘以单limb并累减操作 [numa,n] -= [numb,n] * b

引用了 lmmp_debug_assert, lmmp_dec_1, lmmp_param_assert, lmmp_submul_1_() , 以及 n.

被这些函数引用 lmmp_divexact_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_divexact_divide_()

void lmmp_divexact_divide_ ( mp_ptr restrict  dst,
mp_srcptr restrict  np,
mp_size_t  nn,
mp_srcptr restrict  dp,
mp_size_t  dn 
)

在文件 divexact.c243 行定义.

243 {
244 lmmp_param_assert(dst != NULL && np != NULL && dp != NULL);
246 lmmp_param_assert(nn >= dn);
247 lmmp_param_assert((dp[0] & 1) != 0);
248
249 mp_size_t qn = nn - dn + 1;
251 mp_size_t rn = qn - qn / 2;
252 qn = qn / 2;
253
254 TEMP_DECL;
258 lmmp_mullo_n_(dst, np, dinv, rn, tp);
259 if (qn == 0) {
260 TEMP_FREE;
261 return;
262 }
263
264 lmmp_debug_assert(3 * rn >= qn + rn);
265 lmmp_mul_(tp, dp, qn + rn, dst, rn);
266
267 // 即使存在错位,高位的np也一定可以将其约减去,因此无需进行任何处理
268 lmmp_sub_n_(tp, np + rn, tp + rn, qn);
269 lmmp_mullo_n_(dst + rn, tp, dinv, qn, tp + rn);
270 TEMP_FREE;
271}
static void lmmp_mullo_n_(mp_ptr restrict dst, mp_srcptr restrict numa, mp_srcptr restrict numb, mp_size_t n, mp_ptr restrict tp)
Definition divexact.c:106
void lmmp_mul_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
不等长大数乘法操作 [dst,na+nb] = [numa,na] * [numb,nb]
mp_limb_t lmmp_sub_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
无借位的n位减法 [dst,n] = [numa,n] - [numb,n]
Definition sub_n.c:80
void lmmp_binvert_n_dc_(mp_ptr dst, mp_srcptr numa, mp_size_t n, mp_ptr tp)
计算 [numa,n] 在 B^n 下的逆元

引用了 lmmp_binvert_n_dc_(), lmmp_debug_assert, lmmp_mul_(), lmmp_mullo_n_(), lmmp_param_assert, lmmp_sub_n_(), n, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

被这些函数引用 lmmp_divexact_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_divexact_unbalanced_()

void lmmp_divexact_unbalanced_ ( mp_ptr  dst,
mp_srcptr  np,
mp_size_t  nn,
mp_srcptr restrict  dp,
mp_size_t  dn,
mp_ptr restrict  dinv 
)

在文件 divexact.c160 行定义.

167 {
168 lmmp_param_assert(dst != NULL && np != NULL && dp != NULL);
170 lmmp_param_assert(nn >= dn);
171 lmmp_param_assert((dp[0] & 1) != 0);
172
173 TEMP_DECL;
175 if (dinv == NULL) {
178 }
179
180#define c (tp) // [tp, dn]
181#define l (tp + dn) // [tp + dn, dn]
182#define scratch (tp + 2 * dn) // [tp + 2 * dn, 2*dn]
183
184 mp_size_t i = 0, qn = nn - dn + 1;
186 lmmp_zero(c, dn);
187 if (qn > dn) {
188 for (; i < qn - dn; i += dn) {
189 lmmp_sub_n_(l, np + i, c, dn);
190 ca = lmmp_cmp_(l, np + i, dn) == 1 ? 1 : 0;
191 /*
192 FIXME: 这里的循环中,第二个乘数dinv以及dp,始终保持不变
193 在拥有可以惰性初始化的FFT算法的情况下,可以节省numa的正变换
194 在循环的情况下,这将会有可观的性能提升
195 */
198 //lmmp_mul_n_(scratch, dst + i, dp, dn);
199 if (ca) {
200 lmmp_add_1_(c, scratch + dn, dn, 1);
201 } else {
202 lmmp_copy(c, scratch + dn, dn);
203 }
204 }
205 }
206 lmmp_sub_n_(l, np + i, c, dn);
207 lmmp_mullo_n_(dst + i, l, dinv, qn - i, scratch);
208 TEMP_FREE;
209#undef c
210#undef l
211#undef scratch
212}
#define scratch
static void lmmp_mulhi_n_(mp_ptr dst, mp_srcptr restrict lop, mp_srcptr restrict numa, mp_srcptr restrict numb, mp_size_t n, mp_ptr tp)
已知乘积的低位,计算乘积的高位
Definition divexact.c:130
#define lmmp_zero(dst, n)
Definition lmmp.h:369
static int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:996
static mp_limb_t lmmp_add_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数加单精度数静态内联函数 [dst,na]=[numa,na]+x
Definition lmmpn.h:1103

引用了 c, l, lmmp_add_1_(), lmmp_binvert_n_dc_(), lmmp_cmp_(), lmmp_copy, lmmp_mulhi_n_(), lmmp_mullo_n_(), lmmp_param_assert, lmmp_sub_n_(), lmmp_zero, n, scratch, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

被这些函数引用 lmmp_divexact_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_mulhi_n_()

static void lmmp_mulhi_n_ ( mp_ptr  dst,
mp_srcptr restrict  lop,
mp_srcptr restrict  numa,
mp_srcptr restrict  numb,
mp_size_t  n,
mp_ptr  tp 
)
inlinestatic

已知乘积的低位,计算乘积的高位

参数
dst乘积的高位,长度为 n
lop乘积的低位,长度为 n
numa乘数a
numb乘数b
n乘数a和乘数b的 limb 长度
tp临时空间(应需要2*n个limb)
警告
eqsep(dst,tp)

在文件 divexact.c130 行定义.

137 {
140 lmmp_copy(dst, tp + n, n);
141 } else {
142 mp_limb_t c;
143 mp_size_t m = lmmp_fft_next_size_((n * 2 + 1) >> 1);
144 lmmp_debug_assert(n * 2 > m && m >= n);
146 c = lmmp_sub_(tp, tp, m, lop, n);
147 if (c != 0)
148 lmmp_dec(tp);
149 if (m == n) {
150 lmmp_copy(dst, tp, n);
151 } else {
152 mp_size_t fn = m - n;
153 mp_size_t sn = n - fn;
154 lmmp_copy(dst, tp + n, fn);
155 lmmp_copy(dst + fn, tp, sn);
156 }
157 }
158}
#define lmmp_mul_n_
Definition inlines.h:167
void lmmp_mul_mersenne_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
梅森数模乘法 [dst,rn] = [numa,na]*[numb,nb] mod B^rn-1
Definition mul_fft.c:761
#define lmmp_dec(p)
大数减1宏(预期无借位)
Definition lmmpn.h:965
mp_size_t lmmp_fft_next_size_(mp_size_t n)
计算满足 >=n 的最小费马/梅森乘法可行尺寸
Definition mul_fft.c:95
static mp_limb_t lmmp_sub_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数减法静态内联函数 [dst,na]=[numa,na]-[numb,nb]
Definition lmmpn.h:1064
#define MULHI_MERSENNE_THRESHOLD
Definition mparam.h:121
#define numb

引用了 c, lmmp_copy, lmmp_debug_assert, lmmp_dec, lmmp_fft_next_size_(), lmmp_mul_mersenne_(), lmmp_mul_n_, lmmp_sub_(), MULHI_MERSENNE_THRESHOLD, n, numb , 以及 tp.

被这些函数引用 lmmp_divexact_unbalanced_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_mullo_n_()

static void lmmp_mullo_n_ ( mp_ptr restrict  dst,
mp_srcptr restrict  numa,
mp_srcptr restrict  numb,
mp_size_t  n,
mp_ptr restrict  tp 
)
inlinestatic

在文件 divexact.c106 行定义.

112 {
113 if (n < MULLO_DC_THRESHOLD) {
115 } else {
117 }
118}
void lmmp_mullo_dc_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_ptr tp, mp_size_t n)
低位乘法 [dst,n] = [numa,n] * [numb,n] mod B^n
void lmmp_mullo_fft_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n, mp_ptr scratch)
低位FFT乘法 [dst,n] = [numa,n] * [numb,n] mod B^n
Definition mullo.c:22
#define MULLO_DC_THRESHOLD
Definition mparam.h:59

引用了 lmmp_mullo_dc_(), lmmp_mullo_fft_(), MULLO_DC_THRESHOLD, n, numb , 以及 tp.

被这些函数引用 lmmp_divexact_divide_() , 以及 lmmp_divexact_unbalanced_().

+ 函数调用图:
+ 这是这个函数的调用关系图: