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

浏览源代码.

函数

mp_limb_t lmmp_div_mulinv_ (mp_ptr restrict dstq, mp_ptr restrict numa, mp_size_t na, mp_srcptr restrict numb, mp_size_t nb, mp_srcptr restrict invappr, mp_size_t ni)
 
void lmmp_inv_prediv_ (mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t ni)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 

函数说明

◆ lmmp_div_mulinv_()

mp_limb_t lmmp_div_mulinv_ ( mp_ptr restrict  dstq,
mp_ptr restrict  numa,
mp_size_t  na,
mp_srcptr restrict  numb,
mp_size_t  nb,
mp_srcptr restrict  invappr,
mp_size_t  ni 
)

在文件 div_mulinv.c47 行定义.

55 {
56 lmmp_param_assert(na >= nb && nb >= ni);
57 lmmp_param_assert(ni > 0);
59 mp_size_t nq = na - nb, ntp = LMMP_MIN(ni, nq) + nb;
63
64 numa += nq;
65 dstq += nq;
66
67 qh = lmmp_cmp_(numa, numb, nb) >= 0;
68 if (qh) {
70 }
71 while (nq) {
72 if (nq < ni) {
73 invappr += ni - nq;
74 ni = nq;
75 }
76 numa -= ni;
77 dstq -= ni;
78 nq -= ni;
79
80 lmmp_mul_n_(tp, numa + nb, invappr, ni);
81 lmmp_assert(lmmp_add_n_(dstq, tp + ni, numa + nb, ni) == 0);
82
83 mp_size_t mn, wn;
85
86 if (nb < DIV_MULINV_MODM_THRESHOLD || (mn = lmmp_fft_next_size_(nb + 1)) >= nb + ni) {
87 lmmp_mul_(tp, numb, nb, dstq, ni); // nb+ni limbs, high 'ni' cancels
88 } else {
89 // 0<wn<ni<=nb<mn<nb+ni
90 wn = nb + ni - mn;
91
92 // x=b*q
93 // tp=x mod 2^mn-1
94 lmmp_mul_mersenne_(tp, mn, numb, nb, dstq, ni);
95
96 // tp-=ah:0 mod B^mn-1, if result=0, represent it as B^mn-1
97 cy = lmmp_sub_nc_(tp, tp, numa + mn, wn, 1);
98 if (cy)
99 cy = lmmp_sub_1_(tp + wn, tp + wn, mn - wn, 1);
100 if (!cy)
101 lmmp_inc(tp);
102
103 // if al<<tp,
104 if (lmmp_cmp_(numa + nb, tp + nb, mn - nb) < 0) {
105 // maybe ah=xh+1 and al<<xl,
106 // so we subtracted 1 too much when tp-=ah,
107 // now tp=xl-1 mod B^mn-1, and 0<=al<<xl-1<B^mn-1, so tp=xl-1
108 // or ah=xh and al>=xl,
109 // tp=xl mod B^mn-1, the only possibility is we represented xl=0 as tp=B^mn-1
110 // whatever, just inc and then tp=xl
111 tp[mn] = 0; // set a limit
112 lmmp_inc(tp);
113 }
114 }
115
116 mp_limb_t r = numa[nb] - tp[nb];
117 cy = lmmp_sub_n_(numa, numa, tp, nb);
118
119 while ((r -= cy) || lmmp_cmp_(numa, numb, nb) >= 0) {
120 lmmp_inc(dstq);
122 }
123 }
124 TEMP_FREE;
125 return qh;
126}
#define lmmp_mul_n_
Definition inlines.h:167
mp_limb_t * mp_ptr
Definition lmmp.h:80
uint64_t mp_size_t
Definition lmmp.h:77
uint64_t mp_limb_t
Definition lmmp.h:76
#define lmmp_assert(x)
Definition lmmp.h:373
#define LMMP_MIN(l, o)
Definition lmmp.h:351
#define lmmp_param_assert(x)
Definition lmmp.h:401
void lmmp_mul_mersenne_(mp_ptr dst, mp_size_t rn, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
梅森数模乘法 [dst,rn] = [numa,na]*[numb,nb] mod B^rn-1
Definition mul_fft.c:761
static int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:996
#define lmmp_inc(p)
大数加1宏(预期无进位)
Definition lmmpn.h:938
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]
mp_size_t lmmp_fft_next_size_(mp_size_t n)
计算满足 >=n 的最小费马/梅森乘法可行尺寸
Definition mul_fft.c:95
static mp_limb_t lmmp_sub_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数减单精度数静态内联函数 [dst,na]=[numa,na]-x
Definition lmmpn.h:1114
mp_limb_t lmmp_sub_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
无借位的n位减法 [dst,n] = [numa,n] - [numb,n]
Definition sub_n.c:80
mp_limb_t lmmp_sub_nc_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n, mp_limb_t c)
带借位的n位减法 [dst,n] = [numa,n] - [numb,n] - c
Definition sub_n.c:19
mp_limb_t lmmp_add_n_(mp_ptr dst, mp_srcptr numa, mp_srcptr numb, mp_size_t n)
无进位的n位加法 [dst,n] = [numa,n] + [numb,n]
Definition add_n.c:81
#define LIMB_B_2
Definition mparam.h:157
#define DIV_MULINV_MODM_THRESHOLD
Definition mparam.h:38
#define numb
#define tp
#define n
#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

引用了 DIV_MULINV_MODM_THRESHOLD, LIMB_B_2, lmmp_add_n_(), lmmp_assert, lmmp_cmp_(), lmmp_fft_next_size_(), lmmp_inc, LMMP_MIN, lmmp_mul_(), lmmp_mul_mersenne_(), lmmp_mul_n_, lmmp_param_assert, lmmp_sub_1_(), lmmp_sub_n_(), lmmp_sub_nc_(), n, numb, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

+ 函数调用图:

◆ lmmp_inv_prediv_()

void lmmp_inv_prediv_ ( mp_ptr  dst,
mp_srcptr  numa,
mp_size_t  na,
mp_size_t  ni 
)

Copyright (C) 2026 HJimmyK(Jericho Knox)

除法前的逆元预计算,[dst,ni] = invappr( (ni+1 MSLs of numa) + 1 ) / B

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/.

在文件 div_mulinv.c22 行定义.

22 {
23 lmmp_param_assert(na >= ni);
24 lmmp_param_assert(ni > 0);
29
30 if (na == ni) {
31 lmmp_copy(tp + 1, numa, ni);
32 tp[0] = 1;
33 cy = 0;
34 } else {
35 cy = lmmp_add_1_(tp, numa + na - (ni + 1), ni + 1, 1);
36 }
37 if (cy)
38 lmmp_zero(dst, ni);
39 else {
41 lmmp_invappr_(invappr, tp, ni + 1);
42 lmmp_copy(dst, invappr + 1, ni);
43 }
45}
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
#define lmmp_zero(dst, n)
Definition lmmp.h:369
void lmmp_invappr_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
近似逆元计算 (invappr)
static mp_limb_t lmmp_add_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数加单精度数静态内联函数 [dst,na]=[numa,na]+x
Definition lmmpn.h:1103

引用了 LIMB_B_2, lmmp_add_1_(), lmmp_copy, lmmp_invappr_(), lmmp_param_assert, lmmp_zero, n, TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

被这些函数引用 lmmp_div_(), lmmp_div_s_() , 以及 lmmp_to_str_().

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