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

浏览源代码.

函数

static mp_size_t _odd_nPr_ (mp_ptr restrict dst, mp_size_t rn, ulong n, ulong r)
 
static mp_size_t _odd_pow_ (mp_ptr restrict dst, mp_size_t rn, uint base, ulong exp)
 
mp_size_t lmmp_arith_seqprod_ (mp_ptr restrict dst, mp_size_t rn, uint x, uint n, uint m)
 
mp_size_t lmmp_arith_seqprod_size_ (uint x, uint n, uint m)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 
static mp_size_t pow_nPr_ (mp_ptr restrict dst, mp_size_t rn, uint x, uint n, uint m)
 

函数说明

◆ _odd_nPr_()

static mp_size_t _odd_nPr_ ( mp_ptr restrict  dst,
mp_size_t  rn,
ulong  n,
ulong  r 
)
inlinestatic

在文件 arith_seqprod.c47 行定义.

47 {
48 if (n <= NPR_SHORT_LIMIT) {
49 return lmmp_odd_nPr_ushort_(dst, rn, n, r);
50 } else {
51 return lmmp_odd_nPr_uint_(dst, rn, n, r);
52 }
53}
#define NPR_SHORT_LIMIT
Definition mparam.h:151
#define n
mp_size_t lmmp_odd_nPr_ushort_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分
mp_size_t lmmp_odd_nPr_uint_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分

引用了 lmmp_odd_nPr_uint_(), lmmp_odd_nPr_ushort_(), n , 以及 NPR_SHORT_LIMIT.

被这些函数引用 pow_nPr_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _odd_pow_()

static mp_size_t _odd_pow_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  base,
ulong  exp 
)
inlinestatic

在文件 arith_seqprod.c36 行定义.

36 {
37 if (base <= 0xf)
38 return lmmp_u4_pow_1_(dst, rn, base, exp);
39 else if (base <= MP_UCHAR_MAX)
40 return lmmp_u8_pow_1_(dst, rn, base, exp);
41 else if (base <= MP_USHORT_MAX)
42 return lmmp_u16_pow_1_(dst, rn, base, exp);
43 else
44 return lmmp_u32_pow_1_(dst, rn, base, exp);
45}
#define MP_UCHAR_MAX
Definition mparam.h:134
#define MP_USHORT_MAX
Definition mparam.h:135
mp_size_t lmmp_u4_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp
mp_size_t lmmp_u32_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
mp_size_t lmmp_u16_pow_1_(mp_ptr dst, mp_size_t rn, ulong base, ulong exp)
计算幂次方 [dst,rn] = [base,1] ^ exp

引用了 lmmp_u16_pow_1_(), lmmp_u32_pow_1_(), lmmp_u4_pow_1_(), lmmp_u8_pow_1_(), MP_UCHAR_MAX, MP_USHORT_MAX , 以及 n.

被这些函数引用 pow_nPr_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_arith_seqprod_()

mp_size_t lmmp_arith_seqprod_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  x,
uint  n,
uint  m 
)

在文件 arith_seqprod.c100 行定义.

100 {
102 lmmp_param_assert(rn >= 1);
103 lmmp_param_assert(x >= 1);
104 lmmp_param_assert(n >= 1);
105 lmmp_param_assert(m > 1);
106
107 if (x % m == 0) {
108 return pow_nPr_(dst, rn, x, n, m);
109 }
110
111 mp_bitcnt_t bits = 0;
112 while ((x & 1) == 0 && (m & 1) == 0) {
113 x >>= 1;
114 m >>= 1;
115 bits++;
116 }
117 bits *= n + 1;
118
119 TEMP_DECL;
120 ulongp restrict limbs = TALLOC_TYPE((n + 1) / 2 + 1, ulong);
121 mp_size_t limbn = 0;
122 ulong t = 1, s, v;
124 for (uint i = 0; i <= n; i++) {
125 s = x + i * m;
126 ctz_shr_u64(v, s, cnt);
127 t *= v;
128 bits += cnt;
129 if (t > MP_UINT_MAX) {
130 limbs[limbn++] = t;
131 t = 1;
132 }
133 }
134 ctz_shr_u64(v, t, cnt);
135 bits += cnt;
136 if (v != 1) {
137 limbs[limbn++] = v;
138 }
140 bits %= LIMB_BITS;
143 lmmp_zero(dst, shw);
144 if (bits > 0) {
145 dst[shw + bn] = lmmp_shl_(dst + shw, b, bn, bits);
146 rn = bn + shw + 1;
147 rn -= dst[rn - 1] == 0 ? 1 : 0;
148 } else {
149 lmmp_copy(dst + shw, b, bn);
150 rn = bn + shw;
151 }
152 TEMP_FREE;
153 return rn;
154}
static mp_size_t pow_nPr_(mp_ptr restrict dst, mp_size_t rn, uint x, uint n, uint m)
mp_size_t lmmp_elem_mul_ulong_(mp_ptr dst, const ulongp limbs, mp_size_t n, mp_ptr tp)
计算limbs数组的累乘积
#define bn
mp_limb_t * mp_ptr
Definition lmmp.h:80
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
#define lmmp_zero(dst, n)
Definition lmmp.h:369
size_t mp_bitcnt_t
Definition lmmp.h:82
uint64_t mp_size_t
Definition lmmp.h:77
uint64_t mp_limb_t
Definition lmmp.h:76
#define LIMB_BITS
Definition lmmp.h:86
#define lmmp_param_assert(x)
Definition lmmp.h:401
mp_limb_t lmmp_shl_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shl)
大数左移操作 [dst,na] = [numa,na]<<shl,dst的低shl位填充0
Definition shl.c:19
#define ctz_shr_u64(r, x, cnt)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition longlong.h:74
#define MP_UINT_MAX
Definition mparam.h:136
#define t
#define s
uint64_t * ulongp
Definition numth.h:41
uint32_t uint
Definition numth.h:31
uint64_t ulong
Definition numth.h:32
#define TEMP_DECL
Definition tmp_alloc.h:131
#define TEMP_FREE
Definition tmp_alloc.h:150
#define TALLOC_TYPE(n, type)
Definition tmp_alloc.h:148

引用了 bn, ctz_shr_u64, LIMB_BITS, lmmp_copy, lmmp_elem_mul_ulong_(), lmmp_param_assert, lmmp_shl_(), lmmp_zero, MP_UINT_MAX, n, pow_nPr_(), s, t, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

+ 函数调用图:

◆ lmmp_arith_seqprod_size_()

mp_size_t lmmp_arith_seqprod_size_ ( uint  x,
uint  n,
uint  m 
)

Copyright (C) 2026 HJimmyK(Jericho Knox)

计算等差数列乘积 x(x+m)...(x+n*m)的 limb 缓冲区长度

This file is part of LAMMP.

LAMMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed WITHOUT ANY WARRANTY.

See https://www.gnu.org/licenses/.

在文件 arith_seqprod.c24 行定义.

24 {
28 // x(x+m)(x+2m)...(x+nm) <= (x+m*n/2)^(n+1)
29 ulong t = (x + ((ulong)m * n + 1) / 2);
31 // 共有n+1个数,每个数的位数最多为uint,一个limb最多可以容纳两个uint乘积
32 mp_size_t rn2 = (n + 1) / 2 + 1;
33 return LMMP_MIN(rn1, rn2);
34}
#define LMMP_MIN(l, o)
Definition lmmp.h:351
mp_size_t lmmp_pow_1_size_(mp_limb_t base, ulong exp)
计算幂次方需要的limb缓冲区长度 base ^ exp
Definition pow.c:25

引用了 LMMP_MIN, lmmp_param_assert, lmmp_pow_1_size_(), n , 以及 t.

+ 函数调用图:

◆ pow_nPr_()

static mp_size_t pow_nPr_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  x,
uint  n,
uint  m 
)
inlinestatic

在文件 arith_seqprod.c61 行定义.

61 {
63 uint p = x / m;
64
66 mp_size_t tn = lmmp_nPr_size_(p + n, n + 1, &bits);
67 tn -= bits / LIMB_BITS;
69 tn = _odd_nPr_(tp, tn, p + n, n + 1);
70
72 m >>= tz;
75 mpown = _odd_pow_(mpow, mpown, m, n + 1);
76
77 bits += tz * (n + 1);
79 bits %= LIMB_BITS;
80
82 if (tn >= mpown)
83 lmmp_mul_(dst + shw, tp, tn, mpow, mpown);
84 else
85 lmmp_mul_(dst + shw, mpow, mpown, tp, tn);
86
87 rn = tn + mpown;
88 rn -= dst[shw + rn - 1] == 0 ? 1 : 0;
89 if (bits > 0) {
90 dst[shw + rn] = lmmp_shl_(dst + shw, dst + shw, rn, bits);
91 rn += shw + 1;
92 rn -= dst[rn - 1] == 0 ? 1 : 0;
93 } else {
94 rn += shw;
95 }
97 return rn;
98}
static mp_size_t _odd_pow_(mp_ptr restrict dst, mp_size_t rn, uint base, ulong exp)
static mp_size_t _odd_nPr_(mp_ptr restrict dst, mp_size_t rn, ulong n, ulong r)
#define lmmp_tailing_zeros_
Definition inlines.h:161
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 tp
mp_size_t lmmp_nPr_size_(ulong n, ulong r, mp_bitcnt_t *bits)
计算 nPr 排列数的 limb 缓冲区长度

引用了 _odd_nPr_(), _odd_pow_(), LIMB_BITS, lmmp_mul_(), lmmp_nPr_size_(), lmmp_pow_1_size_(), lmmp_shl_(), lmmp_tailing_zeros_, lmmp_zero, n, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

被这些函数引用 lmmp_arith_seqprod_().

+ 函数调用图:
+ 这是这个函数的调用关系图: