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

浏览源代码.

函数

void lmmp_bninv_ (mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
 
static void lmmp_bninv_appr_newton_ (mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 

函数说明

◆ lmmp_bninv_()

void lmmp_bninv_ ( mp_ptr restrict  dstq,
mp_srcptr restrict  numa,
mp_size_t  na,
mp_size_t  ni 
)

在文件 bninv.c136 行定义.

136 {
139 lmmp_param_assert(numa[na - 1] > 0);
140 TEMP_DECL;
141 if (na == 1) {
143 lmmp_zero(bnp, 2 + ni);
144 bnp[2 + ni] = 1;
145 lmmp_div_1_(dstq, bnp, 3 + ni, numa[0]);
146 } else if (na == 2) {
147 mp_size_t bn = 2 * 2 + ni + 1;
149 lmmp_zero(bnp, bn - 1);
150 bnp[bn - 1] = 1;
151 mp_limb_t d[2] = {numa[0], numa[1]};
152 lmmp_div_2_(dstq, bnp, bn, d);
153 } else if (ni > na) {
154 mp_ptr restrict B = TALLOC_TYPE(2 * na + ni + 1, mp_limb_t);
155 lmmp_zero(B, 2 * na + ni);
156 B[2 * na + ni] = 1;
157 lmmp_div_(dstq, NULL, B, 2 * na + ni + 1, numa, na);
158 } else {
159 int shift = lmmp_leading_zeros_(numa[na - 1]);
160 if (shift > 0) {
164 lmmp_shr_(dstq, dstq, na + ni + 2, LIMB_BITS - shift);
165 } else {
167 lmmp_copy(dstq, dstq + 1, na + ni + 1);
168 dstq[na + ni + 1] = 0;
169 }
170 }
171 TEMP_FREE;
172 return;
173}
static void lmmp_bninv_appr_newton_(mp_ptr restrict dstq, mp_srcptr restrict numa, mp_size_t na, mp_size_t ni)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition bninv.c:85
#define bn
#define B
#define lmmp_leading_zeros_
Definition inlines.h:160
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
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_div_1_(mp_ptr dstq, mp_srcptr numa, mp_size_t na, mp_limb_t x)
单精度数除法
Definition div.c:77
void lmmp_div_2_(mp_ptr dstq, mp_srcptr numa, mp_size_t na, mp_ptr numb)
双精度数除法 (除数为2个limb)
Definition div.c:234
mp_limb_t lmmp_shr_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shr)
大数右移操作 [dst,na] = [numa,na]>>shr,dst的高shr位填充0
Definition shr.c:19
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
void lmmp_div_(mp_ptr dstq, mp_ptr dstr, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数除法和取模操作
Definition div.c:74
#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

引用了 B, bn, LIMB_BITS, lmmp_bninv_appr_newton_(), lmmp_copy, lmmp_div_(), lmmp_div_1_(), lmmp_div_2_(), lmmp_leading_zeros_, lmmp_param_assert, lmmp_shl_(), lmmp_shr_(), lmmp_zero, n, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

+ 函数调用图:

◆ lmmp_bninv_appr_newton_()

static void lmmp_bninv_appr_newton_ ( mp_ptr restrict  dstq,
mp_srcptr restrict  numa,
mp_size_t  na,
mp_size_t  ni 
)
static

Copyright (C) 2026 HJimmyK(Jericho Knox)

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

牛顿法求精确逆元(至多产生1的误差)

注解
dstq := B^(2*(na+ni)) // ([numa,na] * B^ni) + [0|1]
警告
eqsep(dstq,numa), dstq!=NULL, numa!=NULL, na>=3, MSB(numa)=1

在文件 bninv.c85 行定义.

85 {
91 mp_ptr restrict bnp = TALLOC_TYPE(2 * na + ni + 1, mp_limb_t);
92 lmmp_zero(bnp, 2 * na + ni + 1);
93 bnp[2 * na + ni] = 1;
95 lmmp_div_basecase_(dstq, bnp, 2 * na + ni + 1, numa, na, inv21);
96 } else {
98
99 mp_size_t N = na + ni;
100 mp_size_t a_hatn = N / 2 + 1;
103 if (remn > ni) {
104 ni_hat = 0;
105 a_hat = numa + na - a_hatn;
106 } else {
107 ni_hat = ni - remn;
108 a_hat = numa;
109 a_hatn = na;
110 }
112 mp_size_t qrn = N + 1 - q_hatn;
114
117
121 // we can assert q_hat_sqr_a[2*q_hatn+na-1] == 0
123 if (2 * qrn + ni > 2 * N) {
124 mp_size_t start = 2 * qrn + ni - 2 * N;
125 lmmp_shl_(q_hat, q_hat, q_hatn, 1); // assert no carry
127 } else {
128 mp_size_t start = 2 * N - 2 * qrn - ni;
129 lmmp_shl_(q_hat, q_hat, q_hatn, 1); // assert no carry
131 }
132 }
133 TEMP_FREE;
134}
#define lmmp_sqr_
Definition inlines.h:166
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
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_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_inv_2_1_(mp_limb_t xh, mp_limb_t xl)
2-1阶逆元计算 (inv21)
Definition inv.c:20
mp_limb_t lmmp_div_basecase_(mp_ptr dstq, mp_ptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb, mp_limb_t inv21)
基础除法运算
#define LIMB_B_2
Definition mparam.h:157
#define BNINV_NEWTON_THRESHOLD
Definition mparam.h:62

引用了 BNINV_NEWTON_THRESHOLD, LIMB_B_2, lmmp_bninv_appr_newton_(), lmmp_div_basecase_(), lmmp_inv_2_1_(), lmmp_mul_(), lmmp_param_assert, lmmp_shl_(), lmmp_sqr_, lmmp_sub_n_(), lmmp_zero, n, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

被这些函数引用 lmmp_bninv_() , 以及 lmmp_bninv_appr_newton_().

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