LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
pow.c
浏览该文件的文档.
1/*
2 * LAMMP - Copyright (C) 2025-2026 HJimmyK(Jericho Knox)
3 * This file is part of lammp, under the GNU LGPL v2 license.
4 * See LICENSE in the project root for the full license text.
5 */
6
7#include "../../../include/lammp/impl/mparam.h"
8#include "../../../include/lammp/impl/tmp_alloc.h"
9#include "../../../include/lammp/lmmpn.h"
10#include "../../../include/lammp/numth.h"
11
12mp_size_t lmmp_pow_(mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp) {
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
const mp_limb_t * mp_srcptr
Definition lmmp.h:216
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
uint64_t ulong
Definition numth.h:36
mp_size_t lmmp_pow_(mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp)
Definition pow.c:12
#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