LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
numth.h
浏览该文件的文档.
1/*
2 * [LAMMP]
3 * Copyright (C) [2025-2026] [HJimmyK(Jericho Knox)]
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#ifndef LAMMP_NUMTH_H
20#define LAMMP_NUMTH_H
21
22#include <math.h>
23#include <stdbool.h>
24
25#include "lmmp.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif // __cplusplus
30
31typedef uint8_t uchar;
32typedef int8_t schar;
33typedef uint16_t ushort;
34typedef int16_t sshort;
35typedef uint32_t uint;
36typedef uint64_t ulong;
37typedef int32_t sint;
38typedef int64_t slong;
39typedef uint8_t* ucharp;
40typedef int8_t* scharp;
41typedef uint16_t* ushortp;
42typedef int16_t* sshortp;
43typedef uint32_t* uintp;
44typedef int32_t* sintp;
45typedef uint64_t* ulongp;
46typedef int64_t* slongp;
47
48#ifndef INLINE_
49#define INLINE_ static inline
50#endif // INLINE_
51
52/**
53 * @brief 计算 a 在2^32下的逆元
54 * @param a 待求逆元
55 * @warning a%2==1
56 * @return 逆元
57 */
59
60/**
61 * @brief 计算 a 在2^64下的逆元
62 * @param a 待求逆元
63 * @warning a%2==1
64 * @return 逆元
65 */
67
68/**
69 * @brief 计算 [numa,2] 在B^2下的逆元
70 * @param numa 待求逆元指针(长度为 2 个limb)
71 * @param dst 结果指针(长度为 2 个limb)
72 * @warning numa!=NULL, dst!=NULL, numa[0]%2==1, eqsep(dst,numa)
73 */
75
76/**
77 * @brief 计算 [numa,3] 在B^3下的逆元
78 * @param numa 待求逆元指针(长度为 3 个limb)
79 * @param dst 结果指针(长度为 3 个limb)
80 * @warning numa!=NULL, dst!=NULL, numa[0]%2==1, sep(dst,numa)
81 */
83
84/**
85 * @brief 计算 [numa,4] 在B^4下的逆元
86 * @param numa 待求逆元指针(长度为 4 个limb)
87 * @param dst 结果指针(长度为 4 个limb)
88 * @warning numa!=NULL, dst!=NULL, numa[0]%2==1, sep(dst,numa)
89 */
91
92/**
93 * @brief 计算 [numa,n] 在B^n下的逆元
94 * @param numa 待求逆元指针(长度为 n 个limb)
95 * @param dst 结果指针(长度为 n 个limb)
96 * @param n 结果的 limb 长度
97 * @param tp 临时工作区指针(长度为 5*(n+1)/2 个limb)
98 * @warning numa!=NULL, dst!=NULL, numa[0]%2==1, sep(dst,numa,tp)
99 */
101
102/**
103 * @brief 计算 [numa,na] 在B^n 下的逆元
104 * @param dst 结果指针(长度为 n 个limb)
105 * @param numa 待求逆元指针(长度为 na 个limb)
106 * @param na 待求逆元的 limb 长度
107 * @param n 结果的 limb 长度
108 * @warning n>=na>0, numa!=NULL, dst!=NULL, numa[0]%2==1, sep(dst,numa)
109 * @return dst 的实际 limb 长度
110 */
111// LAMMP_API mp_size_t lmmp_binvert_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t n);
112
113/**
114 * @brief 计算两个无符号整数的最大公约数
115 * @param u 第一个无符号整数
116 * @param v 第二个无符号整数
117 * @return 最大公约数
118 * @warning u!=0, v!=0
119 */
121
122/**
123 * @brief 计算两个无符号整数的最大公约数
124 * @param up 第一个无符号整数指针
125 * @param un 第一个无符号整数的 limb 长度
126 * @param v 第二个无符号整数
127 * @warning v!=0, up!=NULL, un>0
128 * @return 最大公约数
129 */
131
132/**
133 * @brief 计算两个无符号整数的最大公约数
134 * @param up 第一个无符号整数指针,长度为 2
135 * @param vp 第二个无符号整数指针,长度为 2
136 * @param dst 结果指针(长度为 2,两个 limb 都会进行写入,即使最高位可能为0)
137 * @warning up!=NULL, vp!=NULL, [up,2]!=0, [vp,2]!=0, dst!=NULL, eqsep(dst,[up|vp])
138 * @note 我们不要求 up 和 vp 的高位不为 0,但要求两个数均不可以高低位全为 0
139 * @return dst 的实际 limb 长度
140 */
142
143/**
144 * @brief 计算两个无符号整数的最大公约数
145 * @param up 第一个无符号整数指针
146 * @param un 第一个无符号整数的 limb 长度
147 * @param vp 第二个无符号整数指针,长度为 2
148 * @param dst 结果指针(长度至少为 2,两个 limb 都会进行写入,即使最高位可能为0)
149 * @warning up!=NULL, un>2, vp!=NULL, vp[1]!=0, dst!=NULL, eqsep(dst,[up|vp])
150 * @return dst 的实际 limb 长度
151 */
153
154/**
155 * @brief 计算两个无符号整数的最大公约数(不建议使用此算法,更高版本可能被彻底弃用)
156 * @param dst 结果指针(长度至少为 min(un,vn))
157 * @param up 第一个无符号整数指针
158 * @param un 第一个无符号整数的 limb 长度
159 * @param vp 第二个无符号整数指针
160 * @param vn 第二个无符号整数的 limb 长度
161 * @warning up!=NULL, un>0, vp!=NULL, vn>0, eqsep(dst,[up|vp]), dst!=NULL
162 * @note 朴素的辗转相除法,与Lehmer算法具有相似的渐进时间复杂度,但Lehmer算法绝大多数场合更加优秀
163 * @return dst 的实际 limb 长度
164 */
166
167/**
168 * @brief 计算两个无符号整数的最大公约数(Lehmer算法)
169 * @param dst 结果指针(长度至少为 min(un,vn))
170 * @param up 第一个无符号整数指针
171 * @param un 第一个无符号整数的 limb 长度
172 * @param vp 第二个无符号整数指针
173 * @param vn 第二个无符号整数的 limb 长度
174 * @warning up!=NULL, un>0, vp!=NULL, vn>0, eqsep(dst,[up|vp]), dst!=NULL
175 * @return dst 的实际 limb 长度
176 */
178
179/**
180 * @brief 计算两个无符号整数的乘积,对mod取模,商放入 q 中
181 * @param a 第一个无符号整数
182 * @param b 第二个无符号整数
183 * @param q 商的结果指针
184 * @param mod 取模数
185 * @warning a < mod, b < mod, q!=NULL
186 * @return 余数
187 */
189
190/**
191 * @brief 计算 base^exp 对 mod 取模
192 * @param base 底数
193 * @param exp 指数
194 * @param mod 模数
195 * @warning base < mod, mod > 1
196 * @return base^exp 对 mod 取模的结果
197 */
199
200/**
201 * @brief 计算 base^exp 对 mod 取模
202 * @param base 底数
203 * @param exp 指数
204 * @param mod 模数
205 * @warning base < mod, mod > 1
206 * @return base^exp 对 mod 取模的结果
207 */
209
210/**
211 * @brief 大于n的下一个素数
212 * @param n 起始点(不含)
213 * @warning 如果 n 大于等于ulong可表示最大的质数,则返回ulong_max
214 * @return 大于n的下一个素数
215 */
217
218/**
219 * @brief 小于等于n的上一个素数
220 * @param n 起始点(含)
221 * @warning 如果 n 小于2,则返回 0
222 * @return 小于等于n的上一个素数,如果n恰好为素数,则返回 n
223 */
225
226/**
227 * @brief 判断素数
228 * @param n 待判断的数
229 * @return 若 n 为素数,返回 true,否则返回 false
230 */
232
233/**
234 * @brief 判断素数
235 * @param n 待判断的数
236 * @note 如果 n 的实际值小于2^32,此函数不会调用 lmmp_is_prime_uint_,
237 * 如果你可以保证 n 的实际值小于2^32,使用 lmmp_is_prime_uint_ 将会更快
238 * @return 若 n 为素数,返回 true,否则返回 false
239 */
241
242/**
243 * @brief 计算幂次方需要的limb缓冲区长度 [base,n] ^ exp
244 * @param base 底数指针
245 * @param n 底数 limb 长度
246 * @param exp 指数
247 * @warning n>0, base[n-1]!=0, [base,n]>1
248 * @return 返回值为 [base,n]^exp 需要的 limb 缓冲区长度(比实际长度多 1-2 个limb)
249 */
251 lmmp_param_assert(n > 0);
252 lmmp_param_assert(base[n - 1] != 0);
253 mp_size_t rn = exp * (n - 1) * LIMB_BITS + ceil((double)exp * log2(base[n - 1]));
254 return (rn + LIMB_BITS - 1) / LIMB_BITS + 2; /* more two limbs */
255}
256
257/**
258 * @brief 计算幂次方需要的limb缓冲区长度 base ^ exp
259 * @param base 底数
260 * @param exp 指数
261 * @warning exp>0, base>=1
262 * @return 返回值为 base^exp 需要的 limb 缓冲区长度(比实际长度多 1-2 个limb)
263 */
265 lmmp_param_assert(base >= 1);
266 lmmp_param_assert(exp > 0);
267 return (ceil((double)(exp)*log2((double)base)) + LIMB_BITS - 1) / LIMB_BITS + 2; /* more two limbs */
268}
269
270/**
271 * @brief 计算奇数次幂算法 [dst,rn] = [base,n] ^ exp
272 * @param dst 结果指针
273 * @param rn dst 的 limb 缓冲区长度
274 * @param base 底数指针
275 * @param n 底数的 limb 长度
276 * @param exp 指数
277 * @warning n>0, base[n-1]!=0, sep(dst,base), [base,n]>1, exp>=3, exp%2==1
278 * @return 返回 dst 的实际 limb 长度
279 */
281
282/**
283 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
284 * @param dst 结果指针
285 * @param rn 结果 limb 长度
286 * @param base 底数
287 * @param exp 指数
288 * @warning 1<=base<=0xf, exp>0
289 * @return 返回 dst 的实际 limb 长度
290 */
292
293/**
294 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
295 * @param dst 结果指针
296 * @param rn 结果 limb 长度
297 * @param base 底数
298 * @param exp 指数
299 * @warning 0<base<=0xff, exp>0
300 * @return 返回 dst 的实际 limb 长度
301 */
303
304/**
305 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
306 * @param dst 结果指针
307 * @param rn 结果 limb 长度
308 * @param base 底数
309 * @param exp 指数
310 * @warning 0<base<=0xffff, exp>0
311 * @return 返回 dst 的实际 limb 长度
312 */
314
315/**
316 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
317 * @param dst 结果指针
318 * @param rn 结果 limb 长度
319 * @param base 底数
320 * @param exp 指数
321 * @warning 0<base<=2^32-1, exp>0
322 * @return 返回 dst 的实际 limb 长度
323 */
325
326/**
327 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
328 * @param dst 结果指针
329 * @param rn 结果 limb 长度
330 * @param base 底数
331 * @param exp 指数
332 * @warning 2^32<=base<=2^64-1, exp>0
333 * @return 返回 dst 的实际 limb 长度
334 */
336
337/**
338 * @brief 计算幂次方 [dst,rn] = [base,1] ^ exp
339 * @param dst 结果指针
340 * @param base 底数
341 * @param exp 指数
342 * @warning base>=1, exp>0
343 * @return 返回 dst 的实际 limb 长度
344 */
346
347/**
348 * @brief 计算幂次方2比特窗口快速幂算法 [dst,rn] = [base,n] ^ exp
349 * @param dst 结果指针
350 * @param rn 结果 limb 长度
351 * @param base 底数
352 * @param n 底数的 limb 长度
353 * @param exp 指数
354 * @warning n>0, base[n-1]!=0, sep(dst,base), exp>0
355 * @return 返回 dst 的实际 limb 长度
356 */
358
359/**
360 * @brief 计算大整数幂 [dst,rn] = [base,n] ^ exp
361 * @param dst 结果指针
362 * @param rn 结果 limb 长度
363 * @param base 底数
364 * @param n 底数的 limb 长度
365 * @param exp 指数
366 * @warning n>0, base[n-1]!=0, sep(dst,base), exp>0
367 * @return 返回 dst 的实际 limb 长度
368 */
370
371/**
372 * @brief 计算 nPr 排列数的 limb 缓冲区长度
373 * @param n 排列数的总数
374 * @param r 排列数的选择数
375 * @param bits 被修改为 nPr 的2的因子数
376 * @return nPr 排列数的 limb 缓冲区长度(比实际长度多 1-2 个 limb)
377 */
379
380/**
381 * @brief 计算 nPr 排列数的奇数部分
382 * @param dst 结果指针
383 * @param rn 结果指针的 limb 长度(nPr_size_ 函数的返回值 - bits/LIMB_BITS)
384 * @param n 排列数的总数
385 * @param r 排列数的选择数
386 * @warning 0xffff>=n>=r, dst!=NULL, rn>0
387 * @return 返回 dst 的实际 limb 长度
388 */
390
391/**
392 * @brief 计算 nPr 排列数的奇数部分
393 * @param dst 结果指针
394 * @param rn 结果指针的 limb 长度(nPr_size_ 函数的返回值 - bits/LIMB_BITS)
395 * @param n 排列数的总数
396 * @param r 排列数的选择数
397 * @warning 0xffffffff>=n>=r, dst!=NULL, rn>0
398 * @return 返回 dst 的实际 limb 长度
399 */
401
402/**
403 * @brief 计算 nPr 排列数的奇数部分
404 * @param dst 结果指针
405 * @param rn 结果指针的 limb 长度(nPr_size_ 函数的返回值 - bits/LIMB_BITS)
406 * @param n 排列数的总数
407 * @param r 排列数的选择数
408 * @warning n>=r, dst!=NULL, rn>0
409 * @return 返回 dst 的实际 limb 长度
410 */
412
413/**
414 * @brief 计算 nPr 排列数 ( nPr = n! / (n-r)! )
415 * @param dst 结果指针
416 * @param bits nPr 的2的因子数
417 * @param rn 结果指针的 limb 长度
418 * @param n 排列数的总数
419 * @param r 排列数的选择数
420 * @warning n>=r, dst!=NULL, rn>0
421 * @return 返回 dst 的实际 limb 长度
422 */
424
425/**
426 * @brief 计算 n! 阶乘的 limb 缓冲区长度
427 * @param n 阶乘的阶数
428 * @param bits 被修改为 n! 的2的因子数
429 * @return n! 阶乘的 limb 缓冲区长度(比实际长度多 1-2 个 limb)
430 */
432
433/**
434 * @brief 计算 n! 阶乘的奇数部分
435 * @param dst 结果指针
436 * @param rn 结果指针的 limb 长度(factorial_size_ 函数的返回值 - bits/LIMB_BITS)
437 * @param n 阶乘的阶数
438 * @warning n>0xffff, dst!=NULL, rn>0
439 * @return 返回 dst 的实际 limb 长度
440 */
442
443/**
444 * @brief 计算 n! 阶乘
445 * @param dst 结果指针
446 * @param bits n! 的2的因子数
447 * @param rn 结果指针的 limb 长度
448 * @param n 阶乘的阶数
449 * @warning dst!=NULL, rn>0
450 * @return 返回 dst 的实际 limb 长度
451 */
453
454/**
455 * @brief 计算 nCr 组合数的 limb 缓冲区长度
456 * @param n 组合数的总数
457 * @param r 组合数的选择数
458 * @param bits 被修改为 nCr 的2的因子数
459 * @return nCr 组合数的 limb 缓冲区长度(比实际长度多 1-2 个 limb)
460 */
462
463/**
464 * @brief 计算 nCr 组合数的奇数部分
465 * @param dst 结果指针
466 * @param rn 结果指针的 limb 长度
467 * @param n 组合数的总数
468 * @param r 组合数的选择数
469 * @return 返回 dst 的实际 limb 长度
470 * @warning r<=n/2, n<=0xffff, dst!=NULL, rn>0
471 */
473
474/**
475 * @brief 计算 nCr 组合数的奇数部分
476 * @param dst 结果指针
477 * @param rn 结果指针的 limb 长度
478 * @param n 组合数的总数
479 * @param r 组合数的选择数
480 * @return 返回 dst 的实际 limb 长度
481 * @warning r<=n/2, 0xffff<n, dst!=NULL, rn>0
482 */
484
485/**
486 * @brief 计算 nCr 组合数 ( nCr = n! / (r!(n-r)!) )
487 * @param dst 结果指针
488 * @param bits nCr 的2的因子数
489 * @param rn 结果指针的 limb 长度
490 * @param n 组合数的总数
491 * @param r 组合数的选择数
492 * @return 返回 dst 的实际 limb 长度
493 * @warning r<=n/2, n<=0xffffffff, dst!=NULL, rn>0
494 */
496
497/**
498 * @brief 计算多项式系数的 limb 缓冲区长度
499 * @param r 需要计算的系数的数组
500 * @param m 系数的个数
501 * @param n 输出变量,将会被修改为 r[i] 的总和,即r1+r2+...+rm
502 * @return 多项式系数的 limb 缓冲区长度(比实际长度多 1-2 个 limb)
503 * @note 多项式系数为 ( r1+r2+...+rm )! / ( r1! * r2! * ... * rm!)
504 * @warning 我们使用 ulong* n 来同时计算 r[i] 的总和,因为 n 可能超过 0xffffffff。
505 * 我们预计算 n,这不仅可以作为后续多项式系数函数的参数传入。
506 * 同时也请调用者注意判断 n 是否超过了 0xffffffff
507 * 这是 lmmp_multinomial_ 函数的限制。
508 */
510
511/**
512 * @brief 计算多项式系数
513 * @param dst 结果指针
514 * @param rn 结果指针的 limb 长度
515 * @param n r[i] 的总和
516 * @param r 需要计算的系数的数组
517 * @param m 系数的个数
518 * @warning m>1, n>0
519 * @note 多项式系数为 ( r1+r2+...+rm )! / ( r1! * r2! * ... * rm!)
520 * @return 返回 dst 的实际 limb 长度
521 */
523
524/**
525 * @brief 计算等差数列乘积 x(x+m)...(x+n*m)的 limb 缓冲区长度
526 * @param x 首项
527 * @param n 等差数列共n+1项
528 * @param m 公差
529 * @warning x>0, m>1, n>0
530 * @return 等差数列乘积的 limb 缓冲区长度(比实际长度多 1-2 个 limb)
531 */
533
534/**
535 * @brief 计算等差数列乘积 x(x+m)...(x+n*m)
536 * @param dst 结果指针
537 * @param rn 结果指针的 limb 长度
538 * @param x 首项
539 * @param n 等差数列共n+1项
540 * @param m 公差(大于1)
541 * @warning x>0, m>1, n>0, dst!=NULL, rn>0, x+n*m<=0xffffffff
542 * @return 结果的实际的 limb 缓冲区长度
543 */
545
546/**
547 * @brief 试除法
548 * @param num 被除数
549 * @param nn 被除数的 limb 长度
550 * @param N 试除法尝试的质数最大值
551 * @param rn 结果指针的 limb 长度
552 * @warning num!=NULL, nn>0, N>2, rn!=NULL
553 * @note 试除法尝试从 2-N 中所有质数进行试除,如果能整除则会插入到返回结果数组中,没有整除的则会返回 NULL。
554 * @return 结果指针,返回不超过N,且能整除[np,nn]的素数(从小到大排列),若没有能够整除的素数,则返回NULL
555 */
557
558/**
559 * @brief 除去[np,nn]中的[dp,dn]的因子
560 * @param np 被除数指针,将会被修改为除去因子后的数
561 * @param nn 被除数指针的 limb 长度,将会被修改除去因子后的长度
562 * @param dp 除数指针
563 * @param dn 除数指针的 limb 长度
564 * @warning np!=NULL, nn>0, dp!=NULL, dn>0
565 * @note 如果[np,nn]能被[dp,dn]整除,则[np,nn]将被修改为除去因子后的数,nn将被修改为除去因子后的长度。
566 * 如果不能被整除,则[np,nn]保持不变,并返回0。
567 * @return [np,nn]中被[dp,dn]除去的因子的个数,如果不能被整除,则返回0
568 */
570
571#ifdef INLINE_
572#undef INLINE_
573#endif // INLINE_
574
575#ifdef __cplusplus
576}
577#endif // __cplusplus
578
579#endif // LAMMP_NUMTH_H
mp_limb_t * mp_ptr
Definition lmmp.h:215
size_t mp_bitcnt_t
Definition lmmp.h:217
uint64_t mp_size_t
Definition lmmp.h:212
const mp_limb_t * mp_srcptr
Definition lmmp.h:216
uint64_t mp_limb_t
Definition lmmp.h:211
#define LIMB_BITS
Definition lmmp.h:221
#define LAMMP_API
Definition lmmp.h:64
#define lmmp_param_assert(x)
Definition lmmp.h:398
#define tp
mp_size_t lmmp_odd_nCr_uint_(mp_ptr dst, mp_size_t rn, uint n, uint r)
计算 nCr 组合数的奇数部分
mp_size_t lmmp_multinomial_size_(const uintp r, uint m, ulong *n)
计算多项式系数的 limb 缓冲区长度
ulong lmmp_prev_prime_ulong_(ulong n)
小于等于n的上一个素数
mp_size_t lmmp_odd_factorial_uint_(mp_ptr dst, mp_size_t rn, uint n)
计算 n! 阶乘的奇数部分
mp_size_t lmmp_remove_(mp_ptr np, mp_size_t *nn, mp_srcptr dp, mp_size_t dn)
除去[np,nn]中的[dp,dn]的因子
Definition remove.c:56
mp_size_t lmmp_gcd_basecase_(mp_ptr dst, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
计算两个无符号整数的最大公约数(不建议使用此算法,更高版本可能被彻底弃用)
mp_size_t lmmp_gcd_lehmer_(mp_ptr dst, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
计算两个无符号整数的最大公约数(Lehmer算法)
Definition gcd_lehmer.c:233
int16_t * sshortp
Definition numth.h:42
mp_size_t lmmp_u4_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
uint8_t uchar
Definition numth.h:31
mp_size_t lmmp_odd_nPr_ushort_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分
mp_size_t lmmp_pow_win2_(mp_ptr dst, mp_size_t rn, mp_srcptr base, mp_size_t n, ulong exp)
计算幂次方2比特窗口快速幂算法 [dst,rn] = [base,n] ^ exp
mp_size_t lmmp_gcd_2_(mp_ptr dst, mp_srcptr up, mp_size_t un, mp_srcptr vp)
计算两个无符号整数的最大公约数
Definition gcd_2.c:146
ulong lmmp_binvert_ulong_(ulong a)
计算 a 在2^64下的逆元
Definition binvert_1.c:33
mp_size_t lmmp_arith_seqprod_size_(uint x, uint n, uint m)
计算等差数列乘积 x(x+m)...(x+n*m)的 limb 缓冲区长度
void lmmp_binvert_n_dc_(mp_ptr dst, mp_srcptr numa, mp_size_t n, mp_ptr tp)
计算 [numa,n] 在B^n下的逆元
mp_size_t lmmp_u32_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
uint16_t * ushortp
Definition numth.h:41
mp_size_t lmmp_pow_1_(mp_ptr dst, mp_size_t rn, mp_limb_t base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
uint64_t * ulongp
Definition numth.h:45
uint32_t uint
Definition numth.h:35
bool lmmp_is_prime_uint_(uint n)
判断素数
uint lmmp_binvert_uint_(uint a)
计算 a 在2^32下的逆元
Definition binvert_1.c:21
mp_size_t lmmp_pow_basecase_(mp_ptr dst, mp_size_t rn, mp_srcptr base, mp_size_t n, ulong exp)
计算奇数次幂算法 [dst,rn] = [base,n] ^ exp
ulong lmmp_mulmod_ulong_(ulong a, ulong b, ulong mod, ulongp q)
计算两个无符号整数的乘积,对mod取模,商放入 q 中
static mp_size_t lmmp_pow_1_size_(mp_limb_t base, ulong exp)
计算幂次方需要的limb缓冲区长度 base ^ exp
Definition numth.h:264
uint8_t * ucharp
Definition numth.h:39
int8_t * scharp
Definition numth.h:40
mp_limb_t lmmp_gcd_1_(mp_srcptr up, mp_size_t un, mp_limb_t vlimb)
计算两个无符号整数的最大公约数
Definition gcd_1.c:30
uint32_t * uintp
Definition numth.h:43
mp_size_t lmmp_factorial_size_(uint n, mp_bitcnt_t *bits)
计算 n! 阶乘的 limb 缓冲区长度
int64_t slong
Definition numth.h:38
mp_size_t lmmp_u64_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
mp_size_t lmmp_u8_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
void lmmp_binvert_2_(mp_ptr dst, mp_srcptr numa)
计算 [numa,2] 在B^2下的逆元
Definition binvert_1.c:47
int16_t sshort
Definition numth.h:34
mp_size_t lmmp_u16_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
void lmmp_binvert_3_(mp_ptr dst, mp_srcptr numa)
计算 [numa,3] 在B^3下的逆元
uint lmmp_powmod_uint_(uint base, ulong exp, uint mod)
计算 base^exp 对 mod 取模
static mp_size_t lmmp_pow_size_(mp_srcptr base, mp_size_t n, ulong exp)
计算幂次方需要的limb缓冲区长度 [base,n] ^ exp
Definition numth.h:250
int8_t schar
Definition numth.h:32
#define INLINE_
Definition numth.h:49
mp_size_t lmmp_factorial_(mp_ptr dst, mp_bitcnt_t bits, mp_size_t rn, uint n)
计算 n! 阶乘
ulong lmmp_powmod_ulong_(ulong base, ulong exp, ulong mod)
计算 base^exp 对 mod 取模
mp_limb_t lmmp_gcd_11_(mp_limb_t u, mp_limb_t v)
计算 [numa,na] 在B^n 下的逆元
Definition gcd_1.c:10
mp_size_t lmmp_nCr_size_(uint n, uint r, mp_bitcnt_t *bits)
计算 nCr 组合数的 limb 缓冲区长度
void lmmp_binvert_4_(mp_ptr dst, mp_srcptr numa)
计算 [numa,4] 在B^4下的逆元
mp_size_t lmmp_nCr_(mp_ptr dst, mp_bitcnt_t bits, mp_size_t rn, uint n, uint r)
计算 nCr 组合数 ( nCr = n! / (r!(n-r)!) )
Definition nCr.c:231
uint16_t ushort
Definition numth.h:33
mp_size_t lmmp_nPr_size_(ulong n, ulong r, mp_bitcnt_t *bits)
计算 nPr 排列数的 limb 缓冲区长度
mp_size_t lmmp_pow_(mp_ptr dst, mp_size_t rn, mp_srcptr base, mp_size_t n, ulong exp)
计算大整数幂 [dst,rn] = [base,n] ^ exp
int64_t * slongp
Definition numth.h:46
bool lmmp_is_prime_ulong_(ulong n)
判断素数
mp_size_t lmmp_multinomial_(mp_ptr dst, mp_size_t rn, uint n, const uintp r, uint m)
计算多项式系数
uint64_t ulong
Definition numth.h:36
int32_t sint
Definition numth.h:37
ushortp lmmp_trialdiv_(mp_srcptr np, mp_size_t nn, ushort N, ushort *rn)
试除法
mp_size_t lmmp_arith_seqprod_(mp_ptr dst, mp_size_t rn, uint x, uint n, uint m)
计算等差数列乘积 x(x+m)...(x+n*m)
int32_t * sintp
Definition numth.h:44
mp_size_t lmmp_odd_nPr_ulong_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分
mp_size_t lmmp_odd_nCr_ushort_(mp_ptr dst, mp_size_t rn, uint n, uint r)
计算 nCr 组合数的奇数部分
ulong lmmp_next_prime_ulong_(ulong n)
大于n的下一个素数
mp_size_t lmmp_nPr_(mp_ptr dst, mp_bitcnt_t bits, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数 ( nPr = n! / (n-r)! )
mp_size_t lmmp_gcd_22_(mp_ptr dst, mp_srcptr up, mp_srcptr vp)
计算两个无符号整数的最大公约数
Definition gcd_2.c:11
mp_size_t lmmp_odd_nPr_uint_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分