LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
trialdiv.c
浏览该文件的文档.
1/*
2 * LAMMP - Copyright (C) 2025-2026 HJimmyK(Jericho Knox)
3 * This file is part of lammp, under the GNU LGPL v2 license.
4 * See LICENSE in the project root for the full license text.
5 */
6
7#include "../../../include/lammp/numth.h"
8#include "../../../include/lammp/lmmpn.h"
9#include "../../../include/lammp/impl/prime_table.h"
10#include "../../../include/lammp/impl/tmp_alloc.h"
11#include "../../../include/lammp/impl/ele_mul.h"
12
13#define MAX_T 0xffffffffffffull
14
16 if (np == NULL || nn == 0) {
17 *rn = 0;
18 return NULL;
19 }
20 ulong t = 1;
21 ushort idx[20];
22 uint idx_cnt = 0;
23 ushort retn_max = 10;
24 ushortp ret = ALLOC_TYPE(retn_max, ushort);
25 ushort retn = 0;
26 if (!(np[0] & 1)) {
27 ret[retn++] = 2;
28 }
29 for (mp_size_t i = 1;; i++) {
31 if (p > N || i >= PRIME_SHORT_TABLE_SIZE - 1) break;
32 t *= p;
33 idx[idx_cnt++] = p;
34 if (t > MAX_T || idx_cnt == 20) {
35 mp_limb_t r = lmmp_mod_1_(np, nn, t);
36 for (uint j = 0; j < idx_cnt; j++) {
37 if (r == 0 || r % idx[j] == 0) {
38 ret[retn++] = idx[j];
39 if (retn == retn_max) {
40 retn_max = retn_max * 12 / 10;
41 ret = REALLOC_TYPE(ret, retn_max, ushort);
42 }
43 }
44 }
45 idx_cnt = 0;
46 t = 1;
47 }
48 }
49 if (idx_cnt > 0) {
50 mp_limb_t r = lmmp_mod_1_(np, nn, t);
51 for (uint j = 0; j < idx_cnt; j++) {
52 if (r == 0 || r % idx[j] == 0) {
53 ret[retn++] = idx[j];
54 if (retn == retn_max) {
55 retn_max += 10;
56 ret = REALLOC_TYPE(ret, retn_max, ushort);
57 }
58 }
59 }
60 }
61 if (retn == 0) {
62 lmmp_free(ret);
63 *rn = 0;
64 return NULL;
65 } else {
66 *rn = retn;
67 return ret;
68 }
69}
70
72 ushort primen = lmmp_prime_cnt16_(N);
73 if (primen > 4 * nn) {
74 return lmmp_trialdiv_short_(np, nn, N, rn);
75 } else {
76 /*
77 if [np,nn] is too large, we calculate the product of primes up to N,
78 and divide [np,nn] by the product to get remainder.
79 */
81 ulongp restrict pp = SALLOC_TYPE(primen / 4, ulong);
82 ulong t = 1;
83 pp[0] = 1;
84 mp_size_t pn = 1;
85 for (ushort i = 0; i < primen; i++) {
86 t *= prime_short_table[i];
87 if (t > MAX_T) {
88 pp[pn++] = t;
89 t = 1;
90 }
91 }
92 if (t > 1) {
93 pp[pn++] = t;
94 }
95 mp_ptr restrict prod = SALLOC_TYPE(pn * 2, mp_limb_t);
96 pn = lmmp_elem_mul_ulong_(prod, pp, pn, prod + pn);
97
98 lmmp_div_(NULL, prod, np, nn, prod, pn);
99 while (pn > 0 && prod[pn - 1] == 0) --pn;
100 ushortp restrict ret;
101 if (pn == 0) {
102 ret = ALLOC_TYPE(primen, ushort);
103 for (ushort i = 0; i < primen; i++) {
104 ret[i] = prime_short_table[i];
105 }
106 *rn = primen;
107 } else {
108 ret = lmmp_trialdiv_short_(prod, pn, N, rn);
109 }
111 return ret;
112 }
113}
mp_size_t lmmp_elem_mul_ulong_(mp_ptr dst, const ulongp limbs, mp_size_t n, mp_ptr tp)
计算limbs数组的累乘积
mp_limb_t * mp_ptr
Definition lmmp.h:215
uint64_t mp_size_t
Definition lmmp.h:212
const mp_limb_t * mp_srcptr
Definition lmmp.h:216
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:204
uint64_t mp_limb_t
Definition lmmp.h:211
mp_limb_t lmmp_mod_1_(mp_srcptr numa, mp_size_t na, mp_limb_t x)
单精度数取余
Definition div.c:20
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:57
uint16_t * ushortp
Definition numth.h:41
uint64_t * ulongp
Definition numth.h:45
uint32_t uint
Definition numth.h:35
uint16_t ushort
Definition numth.h:33
uint64_t ulong
Definition numth.h:36
#define PRIME_SHORT_TABLE_SIZE
Definition prime_table.h:30
const ushort prime_short_table[6542]
ushort lmmp_prime_cnt16_(ushort n)
计算小于等于 n 的素数数量
#define REALLOC_TYPE(p, new_size, type)
Definition tmp_alloc.h:114
#define ALLOC_TYPE(n, type)
Definition tmp_alloc.h:112
#define SALLOC_TYPE(n, type)
Definition tmp_alloc.h:87
#define TEMP_S_DECL
Definition tmp_alloc.h:76
#define TEMP_S_FREE
Definition tmp_alloc.h:105
#define MAX_T
Definition trialdiv.c:13
ushortp lmmp_trialdiv_(mp_srcptr restrict np, mp_size_t nn, ushort N, ushort *rn)
Definition trialdiv.c:71
static ushortp lmmp_trialdiv_short_(mp_srcptr restrict np, mp_size_t nn, ushort N, ushort *rn)
Definition trialdiv.c:15