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

浏览源代码.

函数

mp_size_t lmmp_pow_ (mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp)
 

函数说明

◆ lmmp_pow_()

mp_size_t lmmp_pow_ ( mp_ptr restrict  dst,
mp_size_t  rn,
mp_srcptr restrict  base,
mp_size_t  n,
ulong  exp 
)

在文件 pow.c12 行定义.

12 {
13 lmmp_param_assert(n > 0);
14 lmmp_param_assert(exp > 0);
15 lmmp_param_assert(base[n - 1] != 0);
16 if (exp == 1) {
17 lmmp_copy(dst, base, n);
18 return n;
19 } else if (exp == 2) {
20 lmmp_sqr_(dst, base, n);
21 rn = n << 1;
22 rn -= (dst[rn - 1] == 0);
23 return rn;
24 } else {
25 mp_size_t base_tz = 0;
26 while (*base == 0) {
27 ++base_tz;
28 ++base;
29 --n;
30 }
31 base_tz *= exp;
32 lmmp_zero(dst, base_tz);
33 dst += base_tz;
34 if (n == 1) {
35 if (exp <= POW_1_EXP_THRESHOLD) {
36 dst[0] = base[0];
37 rn = 1;
38 for (mp_size_t i = 1; i < exp; ++i) {
39 dst[rn] = lmmp_mul_1_(dst, dst, rn, base[0]);
40 ++rn;
41 rn -= (dst[rn - 1] == 0);
42 }
43 return rn + base_tz;
44 } else {
45 return lmmp_pow_1_(dst, rn, base[0], exp) + base_tz;
46 }
47 } else { /* n > 2 */
49 if ((exp % 4 == 3) || (2 * lmmp_limb_popcnt_(exp) >= (lmmp_limb_bits_(exp)))) {
50 return lmmp_pow_win2_(dst, rn, base, n, exp) + base_tz;
51 }
52 }
53 if (exp & 1) {
54 return lmmp_pow_basecase_(dst, rn, base, n, exp) + base_tz;
55 }
56
57 int tz = lmmp_tailing_zeros_(exp);
59 mp_ptr restrict sq = TALLOC_TYPE((rn + 2) >> 1, mp_limb_t);
60 exp >>= tz;
61
62 if (tz & 1) {
63 if (exp == 1) {
64 lmmp_copy(sq, base, n);
65 rn = n;
66 } else {
67 mp_size_t rn1 = lmmp_pow_size_(base, n, exp);
68 rn = lmmp_pow_basecase_(sq, rn1, base, n, exp);
69 }
70 int i = 2;
71 for (; i <= tz; i += 2) {
72 lmmp_sqr_(dst, sq, rn);
73 rn <<= 1;
74 rn -= (dst[rn - 1] == 0);
75 lmmp_sqr_(sq, dst, rn);
76 rn <<= 1;
77 rn -= (sq[rn - 1] == 0);
78 }
79 lmmp_sqr_(dst, sq, rn);
80 rn <<= 1;
81 rn -= (dst[rn - 1] == 0);
82 } else {
83 if (exp == 1) {
84 lmmp_copy(dst, base, n);
85 rn = n;
86 } else {
87 mp_size_t rn1 = lmmp_pow_size_(base, n, exp);
88 rn = lmmp_pow_basecase_(dst, rn1, base, n, exp);
89 }
90 int i = 2;
91 for (; i <= tz; i += 2) {
92 lmmp_sqr_(sq, dst, rn);
93 rn <<= 1;
94 rn -= (sq[rn - 1] == 0);
95 lmmp_sqr_(dst, sq, rn);
96 rn <<= 1;
97 rn -= (dst[rn - 1] == 0);
98 }
99 }
100 TEMP_FREE;
101 return rn + base_tz;
102 }
103 }
104}
mp_limb_t * mp_ptr
Definition lmmp.h:215
#define lmmp_copy(dst, src, n)
Definition lmmp.h:364
#define lmmp_zero(dst, n)
Definition lmmp.h:366
uint64_t mp_size_t
Definition lmmp.h:212
uint64_t mp_limb_t
Definition lmmp.h:211
#define lmmp_param_assert(x)
Definition lmmp.h:398
int lmmp_tailing_zeros_(mp_limb_t x)
计算一个单精度数(limb)中末尾零的个数
Definition tiny.c:54
void lmmp_sqr_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
大数平方操作 [dst,2*na] = [numa,na]^2
Definition sqr.c:10
int lmmp_limb_bits_(mp_limb_t x)
计算满足 2^k > x 的最小自然数k
Definition tiny.c:11
int lmmp_limb_popcnt_(mp_limb_t x)
计算一个64位无符号整数中1的个数
Definition tiny.c:20
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
#define POW_WIN2_EXP_THRESHOLD
Definition mparam.h:107
#define POW_1_EXP_THRESHOLD
Definition mparam.h:104
#define POW_WIN2_N_THRESHOLD
Definition mparam.h:110
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_pow_1_(mp_ptr dst, mp_size_t rn, mp_limb_t base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
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
static mp_size_t lmmp_pow_size_(mp_srcptr base, mp_size_t n, ulong exp)
计算幂次方需要的limb缓冲区长度 [base,n] ^ exp
Definition numth.h:250
#define TEMP_DECL
Definition tmp_alloc.h:72
#define TEMP_FREE
Definition tmp_alloc.h:93
#define TALLOC_TYPE(n, type)
Definition tmp_alloc.h:91

引用了 lmmp_copy, lmmp_limb_bits_(), lmmp_limb_popcnt_(), lmmp_mul_1_(), lmmp_param_assert, lmmp_pow_1_(), lmmp_pow_basecase_(), lmmp_pow_size_(), lmmp_pow_win2_(), lmmp_sqr_(), lmmp_tailing_zeros_(), lmmp_zero, POW_1_EXP_THRESHOLD, POW_WIN2_EXP_THRESHOLD, POW_WIN2_N_THRESHOLD, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

+ 函数调用图: