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

浏览源代码.

函数

mp_size_t lmmp_from_str_ (mp_ptr dst, const mp_byte_t *src, mp_size_t len, int base)
 字符串转大数操作 [src,len,base] to [dst,return value,B]
 
static mp_size_t lmmp_from_str_basecase_ (mp_ptr dst, const mp_byte_t *src, mp_size_t len, int base)
 将字符串转换为mp_limb_t数组
 
static mp_size_t lmmp_from_str_divide_ (mp_ptr restrict dst, const mp_byte_t *src, mp_size_t len, mp_basepow_t *pow, mp_ptr restrict tp)
 将字符串转换为mp_limb_t数组
 
mp_size_t lmmp_from_str_len_ (const mp_byte_t *src, mp_size_t len, int base)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 

函数说明

◆ lmmp_from_str_()

mp_size_t lmmp_from_str_ ( mp_ptr  dst,
const mp_byte_t src,
mp_size_t  len,
int  base 
)

字符串转大数操作 [src,len,base] to [dst,return value,B]

警告
len>=0, 2<=base<=256
参数
dst大数结果输出指针
src字符串源指针
len字符串长度
base字符串的进制基数
返回
转换后的大数 limb 长度

在文件 from_str.c154 行定义.

154 {
155 lmmp_param_assert(base >= 2 && base <= 256);
156 do {
157 if (len == 0)
158 return 0;
159 } while (src[--len] == 0);
160 ++len;
161
163 if (LMMP_POW2_Q(base)) {
164 mp_limb_t curlimb = 0;
165 const mp_byte_t* srcend = src + len;
166 int bitspd = lmmp_bases_table[base - 2].large_base;
167 int bitpos = 0;
168 limbs = 0;
169
170 do {
172 curlimb |= curdigit << bitpos;
173 bitpos += bitspd;
174 if (bitpos >= LIMB_BITS) {
175 dst[limbs] = curlimb;
176 ++limbs;
177 bitpos -= LIMB_BITS;
178 curlimb = curdigit >> (bitspd - bitpos);
179 }
180 } while (++src != srcend);
181 if (curlimb) {
182 dst[limbs] = curlimb;
183 ++limbs;
184 }
185 } else if (lmmp_from_str_len_(0, len, base) < FROM_STR_BASEPOW_THRESHOLD) {
187 } else {
188 TEMP_DECL;
192 mp_size_t bexp, lexp = (len - 1) / digitspl + 1;
194 // need 1 extra limb to store result
197 mp_ptr tp;
198
199 int cpow = lmmp_limb_bits_(lexp - 1);
200
201 for (int i = cpow; i > 0; --i) {
202 // we will calculate lbase^bexp
203 bexp = ((lexp - 1) >> i) + 1;
204 // we will calculate lbase^(bexp-1) first, and trim it s. t.
205 // it contains at most 2 tailing 0 limb, then multiply it by lbase,
206 // so we need npow limbs to store lbase^bexp
207 mp_size_t npow = lmmp_from_str_len_(0, (bexp - 1) * digitspl + 1, base) + 1;
208
209 if (tzbit) {
210 mp_size_t tzlimb = tzbit * (bexp - 1) / LIMB_BITS;
211 if (tzlimb >= 2)
212 npow -= tzlimb - 2;
213 }
214
215 // space needed for a trimmed npow-limb lbase^bexp
216 alloc_size += npow;
217 }
218
220
221 for (int i = 0; i < 2; ++i) {
222 tp[0] = lbase;
223 powers[i].p = tp;
224 powers[i].np = 1;
225 tp += i + 1;
226 powers[i].zeros = 0;
227 powers[i].digits = digitspl * (i + 1);
228 powers[i].base = base;
229 }
230
231 mp_ptr p = powers[1].p;
232 mp_size_t zeros = 0, np = 1;
233 for (int i = 2; i < cpow; ++i) {
234 lmmp_sqr_(tp, p, np);
235 np *= 2;
236 np -= tp[np - 1] == 0;
237 bexp = (lexp - 1) >> (cpow - i);
238 if (bexp & 1) {
239 cy = lmmp_mul_1_(tp, tp, np, lbase);
240 tp[np] = cy;
241 np += cy != 0;
242 }
243 zeros *= 2;
244 while (tp[0] == 0) {
245 // at most 2 tailing 0 limb here
246 ++zeros;
247 ++tp;
248 --np;
249 }
250 p = tp;
251 powers[i].p = p;
252 powers[i].np = np;
253 powers[i].zeros = zeros;
254 powers[i].digits = digitspl * (bexp + 1);
255 powers[i].base = base;
256 tp += np + 1;
257 }
258
259 for (int i = 1; i < cpow; ++i) {
260 p = powers[i].p;
261 np = powers[i].np;
262 cy = lmmp_mul_1_(p, p, np, lbase);
263 p[np] = cy;
264 np += cy != 0;
265 if (p[0] == 0) {
266 ++powers[i].zeros;
267 ++p;
268 --np;
269 }
270
271 powers[i].p = p;
272 powers[i].np = np;
273 }
274
277
278 TEMP_FREE;
279 }
280 return limbs;
281}
int digits_in_limb
Definition base_table.h:34
const mp_base_t lmmp_bases_table[255]
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition base_table.c:18
mp_limb_t large_base
Definition base_table.h:25
static mp_size_t lmmp_from_str_basecase_(mp_ptr dst, const mp_byte_t *src, mp_size_t len, int base)
将字符串转换为mp_limb_t数组
Definition from_str.c:44
static mp_size_t lmmp_from_str_divide_(mp_ptr restrict dst, const mp_byte_t *src, mp_size_t len, mp_basepow_t *pow, mp_ptr restrict tp)
将字符串转换为mp_limb_t数组
Definition from_str.c:95
mp_size_t lmmp_from_str_len_(const mp_byte_t *src, mp_size_t len, int base)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition from_str.c:23
#define lmmp_limb_bits_
Definition inlines.h:162
#define lmmp_sqr_
Definition inlines.h:166
#define lmmp_tailing_zeros_
Definition inlines.h:161
mp_limb_t * mp_ptr
Definition lmmp.h:80
uint8_t mp_byte_t
Definition lmmp.h:75
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
#define LMMP_POW2_Q(n)
Definition lmmp.h:362
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_mul_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数乘以单limb操作 [dst,na] = [numa,na] * x
#define FROM_STR_BASEPOW_THRESHOLD
Definition mparam.h:74
#define tp
#define n
#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

引用了 BALLOC_TYPE, mp_base_t::digits_in_limb, FROM_STR_BASEPOW_THRESHOLD, mp_base_t::large_base, LIMB_BITS, lmmp_bases_table, lmmp_copy, lmmp_from_str_basecase_(), lmmp_from_str_divide_(), lmmp_from_str_len_(), lmmp_limb_bits_, lmmp_mul_1_(), lmmp_param_assert, LMMP_POW2_Q, lmmp_sqr_, lmmp_tailing_zeros_, n, TEMP_DECL, TEMP_FREE , 以及 tp.

+ 函数调用图:

◆ lmmp_from_str_basecase_()

static mp_size_t lmmp_from_str_basecase_ ( mp_ptr  dst,
const mp_byte_t src,
mp_size_t  len,
int  base 
)
static

将字符串转换为mp_limb_t数组

参数
dst输出数组
src输入字符串
len字符串长度
base转换基数
警告
src[len-1]!=0
返回
返回转换后的limb数量

在文件 from_str.c44 行定义.

44 {
45 lmmp_param_assert(src[len - 1] != 0);
48 mp_size_t limbs = 0, i = len;
49
50 while (i) {
52 if (i >= digitspl) {
53 curlimb = src[--i];
54 for (mp_size_t j = 1; j < digitspl; ++j) {
55 curlimb = curlimb * base + src[--i];
56 }
57 } else {
58 curlimb = src[--i];
59 lbase = base;
60 while (i) {
61 curlimb = curlimb * base + src[--i];
62 lbase *= base;
63 }
64 }
65
66 if (limbs == 0) {
67 dst[0] = curlimb;
68 limbs = 1;
69 } else {
72 if (cy) {
73 dst[limbs] = cy;
74 ++limbs;
75 }
76 }
77 }
78
79 return limbs;
80}
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

引用了 mp_base_t::digits_in_limb, mp_base_t::large_base, lmmp_add_1_(), lmmp_bases_table, lmmp_mul_1_(), lmmp_param_assert , 以及 n.

被这些函数引用 lmmp_from_str_() , 以及 lmmp_from_str_divide_().

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

◆ lmmp_from_str_divide_()

static mp_size_t lmmp_from_str_divide_ ( mp_ptr restrict  dst,
const mp_byte_t src,
mp_size_t  len,
mp_basepow_t pow,
mp_ptr restrict  tp 
)
static

将字符串转换为mp_limb_t数组

参数
dst输出数组
src输入字符串
len字符串长度
pow指数表
tp临时数组
警告
src[len-1]!=0, sep(dst,tp)
注解
第一层调用时:nh>=2, [dst,2*N], [tp,limbs] 后序递归时:N>=2, [dst,limbs+1], [tp,2*N-1] limbs为返回值,N = pow->np + pow->zeros
返回
返回转换后的limb数量

在文件 from_str.c95 行定义.

101 {
102 lmmp_param_assert(src[len - 1] != 0);
104
107 } else {
108 mp_size_t pdigits = pow->digits;
109 if (len <= pdigits) {
111 } else {
112 mp_ptr p = pow->p;
113 mp_size_t np = pow->np;
114 mp_size_t zeros = pow->zeros;
115 mp_ptr lp = tp, hp = tp + np + zeros - 2; // overwrite 2 limbs
116 mp_size_t nl = 0, nh;
117
119 while (llen && src[llen - 1] == 0) --llen;
120 if (llen)
122
123 mp_limb_t save0 = hp[0], save1 = hp[1]; // save 2 limbs
125 if (nh >= np)
126 lmmp_mul_(dst + zeros, hp, nh, p, np);
127 else
128 lmmp_mul_(dst + zeros, p, np, hp, nh);
129 // restore 2 limbs
130 hp[0] = save0;
131 hp[1] = save1;
132
133 if (zeros < nl) {
134 lmmp_copy(dst, lp, zeros);
135 mp_limb_t cy = lmmp_add_n_(dst + zeros, dst + zeros, lp + zeros, nl - zeros);
136 // h*p+l<=(B^nh-1)*p+(p-1)<B^nh*p, limited by nh+np limbs,
137 // so inc won't overflow
138 if (cy)
139 lmmp_inc(dst + nl);
140 } else {
141 lmmp_copy(dst, lp, nl);
142 if (zeros > nl)
143 lmmp_zero(dst + nl, zeros - nl);
144 }
145
146 limbs = nh + np + zeros;
147 limbs -= dst[limbs - 1] == 0;
148 }
149 }
150
151 return limbs;
152}
#define lmmp_zero(dst, n)
Definition lmmp.h:369
#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_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 FROM_STR_DIVIDE_THRESHOLD
Definition mparam.h:72

引用了 FROM_STR_DIVIDE_THRESHOLD, lmmp_add_n_(), lmmp_copy, lmmp_from_str_basecase_(), lmmp_from_str_divide_(), lmmp_from_str_len_(), lmmp_inc, lmmp_mul_(), lmmp_param_assert, lmmp_zero, n , 以及 tp.

被这些函数引用 lmmp_from_str_() , 以及 lmmp_from_str_divide_().

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

◆ lmmp_from_str_len_()

mp_size_t lmmp_from_str_len_ ( const mp_byte_t src,
mp_size_t  len,
int  base 
)

Copyright (C) 2026 HJimmyK(Jericho Knox)

计算字符串转大数所需的 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/.

在文件 from_str.c23 行定义.

23 {
24 lmmp_param_assert(base >= 2 && base <= 256);
25 if (src) {
26 do {
27 if (len == 0)
28 return 1;
29 } while (src[--len] == 0);
30 ++len;
31 }
32 return lmmp_mulh_(len, lmmp_bases_table[base - 2].lg_base) + 1;
33}
#define lmmp_mulh_
Definition inlines.h:165

引用了 lmmp_bases_table, lmmp_mulh_, lmmp_param_assert , 以及 n.

被这些函数引用 lmmp_from_str_(), lmmp_from_str_divide_() , 以及 lmmp_to_str_().

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