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

浏览源代码.

结构体

struct  lehmer_stack_t
 
struct  mp_gcd_lehmer_t
 Copyright (C) 2026 HJimmyK(Jericho Knox) 更多...
 

宏定义

#define A   (gcd->m11)
 
#define A   (M->m11)
 
#define an   (*an)
 
#define an   un
 
#define B   (gcd->m12)
 
#define B   (M->m12)
 
#define bn   (*bn)
 
#define bn   vn
 
#define C   (gcd->m21)
 
#define C   (M->m21)
 
#define D   (gcd->m22)
 
#define D   (M->m22)
 
#define LEHMER_EXACT_BITS   63
 
#define LEHMER_MIN_V   0x100000000ull
 

函数

mp_size_t lmmp_gcd_lehmer_ (mp_ptr dst, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
 计算两个无符号整数的最大公约数(Lehmer算法)
 
static void lmmp_gcd_lehmer_step_ (slong u, slong v, mp_gcd_lehmer_t *gcd)
 
static void lmmp_lehmer_extract_ (mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn, slong *a, slong *b)
 
static bool lmmp_lehmer_mul_ (mp_ptr a, mp_size_t *an, mp_ptr b, mp_size_t *bn, mp_gcd_lehmer_t *M, lehmer_stack_t *ms)
 / a \ = / A B \ * / a \ \ b / \ C D / \ b /

 

结构体说明

◆ lehmer_stack_t

struct lehmer_stack_t

在文件 gcd_lehmer.c90 行定义.

+ lehmer_stack_t 的协作图:
成员变量
mp_size_t mn
mp_ptr mp
mp_size_t nn
mp_ptr np
mp_size_t tn
mp_ptr tp

◆ mp_gcd_lehmer_t

struct mp_gcd_lehmer_t

Copyright (C) 2026 HJimmyK(Jericho Knox)

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/.

在文件 gcd_lehmer.c20 行定义.

+ mp_gcd_lehmer_t 的协作图:
成员变量
slong m11
slong m12
slong m21
slong m22

宏定义说明

◆ A [1/2]

#define A   (gcd->m11)

◆ A [2/2]

#define A   (M->m11)

◆ an [1/2]

#define an   (*an)

◆ an [2/2]

#define an   un

◆ B [1/2]

#define B   (gcd->m12)

◆ B [2/2]

#define B   (M->m12)

◆ bn [1/2]

#define bn   (*bn)

◆ bn [2/2]

#define bn   vn

◆ C [1/2]

#define C   (gcd->m21)

◆ C [2/2]

#define C   (M->m21)

◆ D [1/2]

#define D   (gcd->m22)

◆ D [2/2]

#define D   (M->m22)

◆ LEHMER_EXACT_BITS

#define LEHMER_EXACT_BITS   63

在文件 gcd_lehmer.c26 行定义.

◆ LEHMER_MIN_V

#define LEHMER_MIN_V   0x100000000ull

在文件 gcd_lehmer.c25 行定义.

函数说明

◆ lmmp_gcd_lehmer_()

mp_size_t lmmp_gcd_lehmer_ ( mp_ptr  dst,
mp_srcptr  up,
mp_size_t  un,
mp_srcptr  vp,
mp_size_t  vn 
)

计算两个无符号整数的最大公约数(Lehmer算法)

参数
dst结果指针(长度至少为 min(un,vn)
up第一个无符号整数指针
un第一个无符号整数的 limb 长度
vp第二个无符号整数指针
vn第二个无符号整数的 limb 长度
警告
up!=NULL, un>0, vp!=NULL, vn>0, eqsep(dst,[up|vp]), dst!=NULL
返回
dst 的实际 limb 长度

在文件 gcd_lehmer.c242 行定义.

242 {
243 lmmp_param_assert(un > 0 && vn > 0);
244 lmmp_param_assert(up != NULL && vp != NULL);
246
247 if (un < vn) {
250 } else if (un == vn) {
251 int cmp = lmmp_cmp_(up, vp, un);
252 if (cmp == 0) {
253 lmmp_copy(dst, up, un);
254 return un;
255 } else if (cmp < 0) {
257 }
258 }
259 // u > v
260
262 slong x = 0, y = 0;
263
264#define an un
265#define bn vn
267 // [a,an+1] [b,bn+1]
268 // A * a_old may overlow
272 mp_ptr temp = BALLOC_TYPE((an + 1) * 3, mp_limb_t);
273 ms.tp = temp;
274 ms.mp = temp + (an + 1);
275 ms.np = temp + (an + 1) * 2;
276
277 lmmp_copy(a, up, an);
278 lmmp_copy(b, vp, bn);
279
280 bool bzero = false;
281 while (bzero == false) {
282 if (an > 1 && bn == 1) {
283 dst[0] = lmmp_gcd_1_(a, an, b[0]);
284 return 1;
285 } else if (an == 1 && bn == 1) {
286 dst[0] = lmmp_gcd_11_(a[0], b[0]);
287 return 1;
288 }
289 // a > b
290 lmmp_lehmer_extract_(a, an, b, bn, &x, &y);
292
293 if (M.m21 == 0) {
294 lmmp_div_(NULL, dst, a, an, b, bn);
295 lmmp_copy(a, b, bn);
296 an = bn;
297 while (dst[bn - 1] == 0 && bn > 0) {
298 --bn;
299 }
300 if (bn == 0)
301 bzero = true;
302 else
303 lmmp_copy(b, dst, bn);
304 } else {
305 bzero = lmmp_lehmer_mul_(a, &an, b, &bn, &M, &ms);
306 if ((an < bn) || (an == bn && lmmp_cmp_(a, b, an) < 0)) {
307 LMMP_SWAP(a, b, mp_ptr);
309 }
310 }
311 }
312 lmmp_copy(dst, a, an);
314 return an;
315#undef an
316#undef bn
317}
static void lmmp_gcd_lehmer_step_(slong u, slong v, mp_gcd_lehmer_t *gcd)
Definition gcd_lehmer.c:28
static bool lmmp_lehmer_mul_(mp_ptr a, mp_size_t *an, mp_ptr b, mp_size_t *bn, mp_gcd_lehmer_t *M, lehmer_stack_t *ms)
/ a \ = / A B \ * / a \ \ b / \ C D / \ b /
Definition gcd_lehmer.c:106
#define an
static void lmmp_lehmer_extract_(mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn, slong *a, slong *b)
Definition gcd_lehmer.c:63
#define bn
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition gcd_lehmer.c:20
mp_limb_t * mp_ptr
Definition lmmp.h:80
#define LMMP_SWAP(x, y, type)
Definition lmmp.h:355
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
uint64_t mp_size_t
Definition lmmp.h:77
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_param_assert(x)
Definition lmmp.h:401
static int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:996
void lmmp_div_(mp_ptr dstq, mp_ptr dstr, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数除法和取模操作
Definition div.c:74
#define n
mp_limb_t lmmp_gcd_1_(mp_srcptr up, mp_size_t un, mp_limb_t vlimb)
计算两个无符号整数的最大公约数
Definition gcd_1.c:44
int64_t slong
Definition numth.h:34
mp_limb_t lmmp_gcd_11_(mp_limb_t u, mp_limb_t v)
计算两个无符号整数的最大公约数
Definition gcd_1.c:24
#define TEMP_B_DECL
Definition tmp_alloc.h:132
#define BALLOC_TYPE(n, type)
Definition tmp_alloc.h:146
#define TEMP_B_FREE
Definition tmp_alloc.h:159

引用了 an, BALLOC_TYPE, bn, lmmp_cmp_(), lmmp_copy, lmmp_div_(), lmmp_gcd_11_(), lmmp_gcd_1_(), lmmp_gcd_lehmer_step_(), lmmp_lehmer_extract_(), lmmp_lehmer_mul_(), lmmp_param_assert, LMMP_SWAP, n, TEMP_B_DECL , 以及 TEMP_B_FREE.

+ 函数调用图:

◆ lmmp_gcd_lehmer_step_()

static void lmmp_gcd_lehmer_step_ ( slong  u,
slong  v,
mp_gcd_lehmer_t gcd 
)
static

在文件 gcd_lehmer.c28 行定义.

28 {
29#define A (gcd->m11)
30#define B (gcd->m12)
31#define C (gcd->m21)
32#define D (gcd->m22)
33
34 lmmp_debug_assert(u >= 0 && v >= 0);
36 A = 1; B = 0;
37 C = 0; D = 1;
38
39 while (v != 0) {
40 slong q = u / v;
41 slong t = u % v;
42
43 u = v;
44 v = t;
45
46 t = A - q * C;
47 A = C;
48 C = t;
49 t = B - q * D;
50 B = D;
51 D = t;
52
53 if (v < (slong)LEHMER_MIN_V) break;
54 }
55
56 return;
57#undef A
58#undef B
59#undef C
60#undef D
61}
#define B
#define LEHMER_MIN_V
Definition gcd_lehmer.c:25
#define A
#define C
#define D
#define lmmp_debug_assert(x)
Definition lmmp.h:390
#define t

引用了 A, B, C, D, LEHMER_MIN_V, lmmp_debug_assert, n , 以及 t.

被这些函数引用 lmmp_gcd_lehmer_().

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

◆ lmmp_lehmer_extract_()

static void lmmp_lehmer_extract_ ( mp_srcptr  up,
mp_size_t  un,
mp_srcptr  vp,
mp_size_t  vn,
slong a,
slong b 
)
static

在文件 gcd_lehmer.c63 行定义.

63 {
64 lmmp_param_assert(un > 1 && vn > 1);
67 lmmp_param_assert(a != NULL && b != NULL);
68
69 int kz = lmmp_limb_bits_(up[un - 1]);
70 if (kz >= LEHMER_EXACT_BITS) {
71 *a = up[un - 1] >> (kz - LEHMER_EXACT_BITS);
72 if (vn == un)
73 *b = vp[vn - 1] >> (kz - LEHMER_EXACT_BITS);
74 else
75 *b = 0;
76 } else {
77 *a = up[un - 1] << (LEHMER_EXACT_BITS - kz);
78 *a |= up[un - 2] >> (LIMB_BITS - (LEHMER_EXACT_BITS - kz));
79 if (un > vn + 1) {
80 *b = 0;
81 } else if (un == vn + 1) {
82 *b = vp[vn - 1] >> (LIMB_BITS - (LEHMER_EXACT_BITS - kz));
83 } else {
84 *b = vp[vn - 1] << (LEHMER_EXACT_BITS - kz);
85 *b |= vp[vn - 2] >> (LIMB_BITS - (LEHMER_EXACT_BITS - kz));
86 }
87 }
88}
#define LEHMER_EXACT_BITS
Definition gcd_lehmer.c:26
#define lmmp_limb_bits_
Definition inlines.h:162
#define LIMB_BITS
Definition lmmp.h:86

引用了 LEHMER_EXACT_BITS, LIMB_BITS, lmmp_limb_bits_, lmmp_param_assert , 以及 n.

被这些函数引用 lmmp_gcd_lehmer_().

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

◆ lmmp_lehmer_mul_()

static bool lmmp_lehmer_mul_ ( mp_ptr  a,
mp_size_t an,
mp_ptr  b,
mp_size_t bn,
mp_gcd_lehmer_t M,
lehmer_stack_t ms 
)
static

/ a \ = / A B \ * / a \ \ b / \ C D / \ b /

警告
[a,an] > [b,bn]
注解
不保证返回结果 [a,an] > [b,bn]
返回
a和b是否有一个为0

在文件 gcd_lehmer.c106 行定义.

106 {
107#define A (M->m11)
108#define B (M->m12)
109#define C (M->m21)
110#define D (M->m22)
111#define an (*an)
112#define bn (*bn)
113 if (A == 0) {
114 /* / 0 1 \ / a \
115 \ 1 -q / \ b / */
116 lmmp_debug_assert(B == 1 && C == 1 && D < 0);
117 mp_limb_t c = lmmp_mul_1_(ms->tp, b, bn, -D);
118 if (c == 0)
119 ;
120 else {
121 ++bn;
122 (ms->tp)[bn - 1] = c;
123 }
124 if (an > bn) {
125 lmmp_sub_(a, a, an, b, bn);
126 } else if (an == bn) {
127 int cmp = lmmp_cmp_(a, b, an);
128 if (cmp >= 0)
129 lmmp_sub_(a, a, an, b, bn);
130 else
131 lmmp_sub_(a, b, bn, a, an);
132 } else {
133 lmmp_sub_(a, b, bn, a, an);
134 an = bn;
135 }
136 while (a[an - 1] == 0 && an > 0) {
137 --an;
138 }
139 // return b = b
140 // a = a - q * b
141 return an == 0;
142 } else {
143 if (A < 0) {
144 A = -A;
145 D = -D;
146 } else {
147 B = -B;
148 C = -C;
149 }
150 // A * a + B * b
151 mp_limb_t ca = lmmp_mul_1_(ms->tp, a, an, A);
152 if (ca == 0)
153 ms->tn = an;
154 else {
155 ms->tn = an + 1;
156 (ms->tp)[ms->tn - 1] = ca;
157 }
158 ca = lmmp_mul_1_(ms->mp, b, bn, B);
159 if (ca == 0)
160 ms->mn = bn;
161 else {
162 ms->mn = bn + 1;
163 (ms->mp)[ms->mn - 1] = ca;
164 }
165
166 if (ms->tn > ms->mn) {
167 lmmp_sub_(ms->np, ms->tp, ms->tn, ms->mp, ms->mn);
168 ms->nn = ms->tn;
169 } else if (ms->mn > ms->tn) {
170 lmmp_sub_(ms->np, ms->mp, ms->mn, ms->tp, ms->tn);
171 ms->nn = ms->mn;
172 } else {
173 int cmp = lmmp_cmp_(ms->tp, ms->mp, ms->tn);
174 if (cmp >= 0) {
175 lmmp_sub_(ms->np, ms->tp, ms->tn, ms->mp, ms->mn);
176 ms->nn = ms->tn;
177 } else {
178 lmmp_sub_(ms->np, ms->mp, ms->mn, ms->tp, ms->tn);
179 ms->nn = ms->mn;
180 }
181 }
182 while (ms->np[ms->nn - 1] == 0 && ms->nn > 0) {
183 --(ms->nn);
184 }
185
186 // C * a + D * b
187 ca = lmmp_mul_1_(ms->tp, a, an, C);
188 if (ca == 0)
189 ms->tn = an;
190 else {
191 ms->tn = an + 1;
192 (ms->tp)[ms->tn - 1] = ca;
193 }
194 ca = lmmp_mul_1_(ms->mp, b, bn, D);
195 if (ca == 0)
196 ms->mn = bn;
197 else {
198 ms->mn = bn + 1;
199 (ms->mp)[ms->mn - 1] = ca;
200 }
201
202 if (ms->tn > ms->mn) {
203 lmmp_sub_(a, ms->tp, ms->tn, ms->mp, ms->mn);
204 an = ms->tn;
205 } else if (ms->mn > ms->tn) {
206 lmmp_sub_(a, ms->mp, ms->mn, ms->tp, ms->tn);
207 an = ms->mn;
208 } else {
209 int cmp = lmmp_cmp_(ms->tp, ms->mp, ms->tn);
210 if (cmp >= 0) {
211 lmmp_sub_(a, ms->tp, ms->tn, ms->mp, ms->mn);
212 an = ms->tn;
213 } else {
214 lmmp_sub_(a, ms->mp, ms->mn, ms->tp, ms->tn);
215 an = ms->mn;
216 }
217 }
218 while (a[an - 1] == 0 && an > 0) {
219 --an;
220 }
221
222 // now a = C * a + D * b
223 // ms->np = A * a + B * b
224 if (ms->nn > 0) {
225 lmmp_copy(b, ms->np, ms->nn);
226 bn = ms->nn;
227 return an == 0;
228 } else {
229 b[0] = 0;
230 bn = 0;
231 return true;
232 }
233 }
234#undef A
235#undef B
236#undef C
237#undef D
238#undef an
239#undef bn
240}
#define c
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
mp_limb_t lmmp_mul_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数乘以单limb操作 [dst,na] = [numa,na] * x

引用了 A, an, B, bn, c, C, D, lmmp_cmp_(), lmmp_copy, lmmp_debug_assert, lmmp_mul_1_(), lmmp_sub_() , 以及 n.

被这些函数引用 lmmp_gcd_lehmer_().

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