LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
pow_basecase.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
12#define mul_b(_i_) \
13 lmmp_mul_(dst, sq, rn, b##_i_, b##_i_##n); \
14 rn += b##_i_##n; \
15 rn -= (dst[rn - 1] == 0) ? 1 : 0
16
17mp_size_t lmmp_pow_basecase_(mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp) {
18 lmmp_param_assert(exp >= 3);
19 lmmp_param_assert(exp % 2 == 1);
21
22#define b1 base
23#define b1n n
24 mp_ptr restrict sq = TALLOC_TYPE(rn, mp_limb_t);
25 rn = n;
26 lmmp_copy(dst, base, n);
27 lmmp_sqr_(sq, dst, rn);
28 rn <<= 1;
29 rn -= (sq[rn - 1] == 0) ? 1 : 0;
30 int lz = lmmp_leading_zeros_(exp);
31 int i = 62 - lz;
32 exp <<= lz + 1;
33/*
34 For the intermediate 0, we will skip it entirely until the next 1,
35 and then perform a multiplication. This can reduce the extra copying
36 caused by sparse 1s and improve efficiency.
37 */
38 for ( ; i > 0; ) {
39 lz = lmmp_leading_zeros_(exp);
40 if (lz == 0) {
41 mul_b(1);
42
43 lmmp_sqr_(sq, dst, rn);
44 rn <<= 1;
45 rn -= (sq[rn - 1] == 0) ? 1 : 0;
46 --i;
47 exp <<= 1;
48 } else {
49 int j = 2;
50 if (lz & 1) {
51 lmmp_copy(dst, sq, rn);
52 lmmp_sqr_(sq, dst, rn);
53 rn <<= 1;
54 rn -= (sq[rn - 1] == 0);
55 ++j;
56 for (; j <= lz; j += 2) {
57 lmmp_sqr_(dst, sq, rn);
58 rn <<= 1;
59 rn -= (dst[rn - 1] == 0);
60 lmmp_sqr_(sq, dst, rn);
61 rn <<= 1;
62 rn -= (sq[rn - 1] == 0);
63 }
64 } else {
65 for (; j <= lz; j += 2) {
66 lmmp_sqr_(dst, sq, rn);
67 rn <<= 1;
68 rn -= (dst[rn - 1] == 0);
69 lmmp_sqr_(sq, dst, rn);
70 rn <<= 1;
71 rn -= (sq[rn - 1] == 0);
72 }
73 }
74
75 i -= lz;
76 exp <<= lz;
77 }
78 }
80
81 mul_b(1);
82
84 return rn;
85
86#undef b1
87#undef b1n
88#undef new_b
89}
mp_limb_t * mp_ptr
Definition lmmp.h:215
#define lmmp_copy(dst, src, n)
Definition lmmp.h:364
uint64_t mp_size_t
Definition lmmp.h:212
#define lmmp_debug_assert(x)
Definition lmmp.h:387
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_leading_zeros_(mp_limb_t x)
计算一个单精度数(limb)中前导零的个数
Definition tiny.c:35
void lmmp_sqr_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
大数平方操作 [dst,2*na] = [numa,na]^2
Definition sqr.c:10
#define LIMB_B_2
Definition mparam.h:160
uint64_t ulong
Definition numth.h:36
mp_size_t lmmp_pow_basecase_(mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp)
#define mul_b(_i_)
#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