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

浏览源代码.

函数

mp_size_t lmmp_gcd_22_ (mp_ptr dst, mp_srcptr up, mp_srcptr vp)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 
mp_size_t lmmp_gcd_2_ (mp_ptr dst, mp_srcptr up, mp_size_t un, mp_srcptr vp)
 计算两个无符号整数的最大公约数
 

函数说明

◆ lmmp_gcd_22_()

mp_size_t lmmp_gcd_22_ ( mp_ptr  dst,
mp_srcptr  up,
mp_srcptr  vp 
)

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_2.c27 行定义.

27 {
31 lmmp_param_assert(!(up[1] == 0 && up[0] == 0));
32 lmmp_param_assert(!(vp[1] == 0 && vp[0] == 0));
33 mp_limb_t u[2] = { up[0], up[1] };
34 mp_limb_t v[2] = { vp[0], vp[1] };
35 int k, cnt;
36
37 if (u[1] == 0 && v[1] == 0) {
38 dst[0] = lmmp_gcd_11_(u[0], v[0]);
39 dst[1] = 0;
40 return 1;
41 } else if (u[1] == 0) {
42 cnt = lmmp_tailing_zeros_(u[0] | v[0]);
43 u[0] = u[0] >> lmmp_tailing_zeros_(u[0]);
44 goto gcd_1_2;
45 } else if (v[1] == 0) {
46 cnt = lmmp_tailing_zeros_(u[0] | v[0]);
47 v[0] = v[0] >> lmmp_tailing_zeros_(v[0]);
48 goto gcd_2_1;
49 }
50
51 if (u[0] == 0 && v[0] == 0) {
52 dst[0] = lmmp_gcd_11_(u[1], v[1]);
53 dst[1] = 0;
54 return 1;
55 } else if (u[0] == 0) {
56 u[0] = u[1] >> lmmp_tailing_zeros_(u[1]);
58 goto gcd_1_2;
59 } else if (v[0] == 0) {
60 v[0] = v[1] >> lmmp_tailing_zeros_(v[1]);
62 goto gcd_2_1;
63 }
64 cnt = lmmp_tailing_zeros_(u[0] | v[0]);
66
67 if (k > 0)
68 _u128lshr(u, u, k);
70 if (k > 0)
71 _u128lshr(v, v, k);
72 while (!(u[0] == v[0] && u[1] == v[1])) {
73 if (u[1] == 0 && v[1] != 0) goto gcd_1_2;
74 if (v[1] == 0 && u[1] != 0) goto gcd_2_1;
75 if (u[1] == 0 && v[1] == 0) goto gcd_1_1;
76
77 if (_u128cmp(u, v)) {
78 _u128sub(v, v, u);
79 if (v[0] == 0) {
80 v[0] = v[1] >> lmmp_tailing_zeros_(v[1]);
81 goto gcd_2_1;
82 } else if (v[1] == 0) {
83 v[0] = v[0] >> lmmp_tailing_zeros_(v[0]);
84 goto gcd_2_1;
85 }
87 // k > 0
88 _u128lshr(v, v, k);
89 } else {
90 _u128sub(u, u, v);
91 if (u[0] == 0) {
92 u[0] = u[1] >> lmmp_tailing_zeros_(u[1]);
93 goto gcd_1_2;
94 } else if (u[1] == 0) {
95 u[0] = u[0] >> lmmp_tailing_zeros_(u[0]);
96 goto gcd_1_2;
97 }
99 // k > 0
100 _u128lshr(u, u, k);
101 }
102 }
103 dst[0] = u[0];
104 dst[1] = u[1];
105 if (cnt > 0)
106 _u128lshl(dst, dst, cnt);
107 return 2;
108
109 gcd_1_2: // [u,1] , [v,2]
110 k = lmmp_tailing_zeros_(v[0]);
111 if (k > 0)
112 _u128lshr(v, v, k);
113 while (v[1] != 0) {
114 _u128sub64(v, v, u[0]);
115 if (v[1] == 0)
116 goto gcd_1_1;
117 if (v[0] == 0) {
118 v[0] = v[1] >> lmmp_tailing_zeros_(v[1]);
119 goto gcd_1_1;
120 }
121 k = lmmp_tailing_zeros_(v[0]);
122 // k > 0
123 _u128lshr(v, v, k);
124 }
125 goto gcd_1_1;
126
127 gcd_2_1: // [u,2] , [v,1]
128 k = lmmp_tailing_zeros_(u[0]);
129 if (k > 0)
130 _u128lshr(u, u, k);
131 while (u[1] != 0) {
132 _u128sub64(u, u, v[0]);
133 if (u[1] == 0)
134 goto gcd_1_1;
135 if (u[0] == 0) {
136 u[0] = u[1] >> lmmp_tailing_zeros_(u[1]);
137 goto gcd_1_1;
138 }
139 k = lmmp_tailing_zeros_(u[0]);
140 // k > 0
141 _u128lshr(u, u, k);
142 }
143 goto gcd_1_1;
144
145 gcd_1_1: // [u,1] , [v,1]
146 while (u[0] != v[0]) {
147 if (u[0] > v[0]) {
148 u[0] -= v[0];
149 u[0] >>= lmmp_tailing_zeros_(u[0]);
150 } else {
151 v[0] -= u[0];
152 v[0] >>= lmmp_tailing_zeros_(v[0]);
153 }
154 }
155 dst[0] = u[0];
156 dst[1] = 0;
157 if (cnt > 0)
158 _u128lshl(dst, dst, cnt);
159 return dst[1] == 0 ? 1 : 2;
160}
#define k
#define lmmp_tailing_zeros_
Definition inlines.h:161
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_param_assert(x)
Definition lmmp.h:401
#define _u128lshl(x, y, n)
Definition longlong.h:330
#define _u128sub(r, x, y)
Definition longlong.h:368
#define _u128cmp(x, y)
Definition longlong.h:366
#define _u128lshr(x, y, n)
Definition longlong.h:336
#define _u128sub64(r, x, _i64)
Definition longlong.h:358
#define n
mp_limb_t lmmp_gcd_11_(mp_limb_t u, mp_limb_t v)
计算两个无符号整数的最大公约数
Definition gcd_1.c:24

引用了 _u128cmp, _u128lshl, _u128lshr, _u128sub, _u128sub64, k, lmmp_gcd_11_(), lmmp_param_assert, lmmp_tailing_zeros_ , 以及 n.

被这些函数引用 lmmp_gcd_2_().

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

◆ lmmp_gcd_2_()

mp_size_t lmmp_gcd_2_ ( mp_ptr  dst,
mp_srcptr  up,
mp_size_t  un,
mp_srcptr  vp 
)

计算两个无符号整数的最大公约数

参数
up第一个无符号整数指针
un第一个无符号整数的 limb 长度
vp第二个无符号整数指针,长度为 2
dst结果指针(长度至少为 2,两个 limb 都会进行写入,即使最高位可能为0)
警告
up!=NULL, un>2, vp!=NULL, vp[1]!=0, dst!=NULL, eqsep(dst,[up|vp])
返回
dst 的实际 limb 长度

在文件 gcd_2.c162 行定义.

162 {
167 lmmp_param_assert(vp[1] != 0);
168 mp_limb_t u[2] = {vp[0], vp[1]};
169 lmmp_mod_2_(up, un, u);
170 if (u[1] == 0 && u[0] == 0) {
171 dst[0] = vp[0];
172 dst[1] = vp[1];
173 return 2;
174 } else {
175 return lmmp_gcd_22_(dst, vp, u);
176 }
177}
mp_size_t lmmp_gcd_22_(mp_ptr dst, mp_srcptr up, mp_srcptr vp)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition gcd_2.c:27
void lmmp_mod_2_(mp_srcptr numa, mp_size_t na, mp_ptr numb)
双精度数取余 (除数为2个limb)
Definition div.c:155

引用了 lmmp_gcd_22_(), lmmp_mod_2_(), lmmp_param_assert , 以及 n.

+ 函数调用图: