LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
pow_win2.c
浏览该文件的文档.
1/**
2 * Copyright (C) 2026 HJimmyK(Jericho Knox)
3 *
4 * This file is part of LAMMP.
5 *
6 * LAMMP is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License (LGPL) as published
8 * by the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed WITHOUT ANY WARRANTY.
12 *
13 * See <https://www.gnu.org/licenses/>.
14 */
15
16#include "../../../include/lammp/impl/inlines.h"
17#include "../../../include/lammp/impl/tmp_alloc.h"
18#include "../../../include/lammp/lmmpn.h"
19#include "../../../include/lammp/numth.h"
20
21
22#define mul_b(_i_) \
23 if (rsq) { \
24 if (b##_i_##n >= rn) \
25 lmmp_mul_(dst, b##_i_, b##_i_##n, sq, rn); \
26 else \
27 lmmp_mul_(dst, sq, rn, b##_i_, b##_i_##n); \
28 rn += b##_i_##n; \
29 rn -= (dst[rn - 1] == 0) ? 1 : 0; \
30 rsq = false; \
31 } else { \
32 if (b##_i_##n >= rn) \
33 lmmp_mul_(sq, b##_i_, b##_i_##n, dst, rn); \
34 else \
35 lmmp_mul_(sq, dst, rn, b##_i_, b##_i_##n); \
36 rn += b##_i_##n; \
37 rn -= (sq[rn - 1] == 0) ? 1 : 0; \
38 rsq = true; \
39 }
40
46
47#define b1 base
48#define b1n n
49#define new_b(_i_) mp_ptr restrict b##_i_ = TALLOC_TYPE(b##_i_##n, mp_limb_t)
50
51 mp_size_t b2n = n << 1, b3n = b2n + n;
52 new_b(2);
53 new_b(3);
54
55 lmmp_sqr_(b2, b1, b1n);
56 b2n = b1n << 1;
57 b2n -= b2[b2n - 1] == 0 ? 1 : 0;
58 lmmp_mul_(b3, b2, b2n, b1, b1n);
59 b3n = b2n + b1n;
60 b3n -= b3[b3n - 1] == 0 ? 1 : 0;
61
62 bool rsq = true;
64 rn = 1;
65 int i = 31, j;
66 while ((exp & (0x3ull << ((i--) * 2))) == 0);
67
68 /*
69 模拟一次,让最后一次计算结果恰好是dst,避免最后一次可能的拷贝
70 */
71 for (j = i + 1; j != -1; --j) {
72 int p = (exp & (0x3ull << (j * 2))) >> (j * 2);
73 if (p != 0)
74 rsq = !rsq;
75 }
76 if (rsq) {
77 dst[0] = 1;
78 rsq = false;
79 } else {
80 sq[0] = 1;
81 rsq = true;
82 }
83
84 for (++i; i != -1; --i) {
85 int p = (exp & (0x3ull << (i * 2))) >> (i * 2);
86 if (p == 0) {
87 ;
88 } else if (p == 1) {
89 mul_b(1)
90 } else if (p == 2) {
91 mul_b(2)
92 } else {
93 mul_b(3)
94 }
95
96 if (i > 0) {
97 if (rsq) {
98 lmmp_sqr_(dst, sq, rn);
99 rn <<= 1;
100 rn -= (dst[rn - 1] == 0) ? 1 : 0;
101 lmmp_sqr_(sq, dst, rn);
102 rn <<= 1;
103 rn -= (sq[rn - 1] == 0) ? 1 : 0;
104 } else {
105 lmmp_sqr_(sq, dst, rn);
106 rn <<= 1;
107 rn -= (sq[rn - 1] == 0) ? 1 : 0;
108 lmmp_sqr_(dst, sq, rn);
109 rn <<= 1;
110 rn -= (dst[rn - 1] == 0) ? 1 : 0;
111 }
112 }
113 }
114 lmmp_debug_assert(rsq == false);
115
116 TEMP_FREE;
117 return rn;
118
119#undef b1
120#undef b1n
121#undef new_b
122}
#define lmmp_sqr_
Definition inlines.h:166
mp_limb_t * mp_ptr
Definition lmmp.h:80
uint64_t mp_size_t
Definition lmmp.h:77
#define lmmp_debug_assert(x)
Definition lmmp.h:390
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_param_assert(x)
Definition lmmp.h:401
void lmmp_mul_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
不等长大数乘法操作 [dst,na+nb] = [numa,na] * [numb,nb]
#define b2
#define n
#define b3
uint64_t ulong
Definition numth.h:32
#define b2n
#define b3n
#define b1
mp_size_t lmmp_pow_win2_(mp_ptr restrict dst, mp_size_t rn, mp_srcptr restrict base, mp_size_t n, ulong exp)
Definition pow_win2.c:41
#define b1n
#define new_b(_i_)
#define mul_b(_i_)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition pow_win2.c:22
#define TEMP_DECL
Definition tmp_alloc.h:131
#define TEMP_FREE
Definition tmp_alloc.h:150
#define BALLOC_TYPE(n, type)
Definition tmp_alloc.h:146