LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
divexact.h
浏览该文件的文档.
1/*
2 * [LAMMP]
3 * Copyright (C) [2025-2026] [HJimmyK(Jericho Knox)]
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#ifndef __LAMMP_DIVEXACT_H__
20#define __LAMMP_DIVEXACT_H__
21
22#include "../lmmpn.h"
23
24#define MODLIMB_INVERSE_3 ((mp_limb_t)0xAAAAAAAAAAAAAAAB)
25
26/**
27 * @brief 精确除以3([dst,na] = [numa,na] / 3)
28 * @param dst 结果存储位置
29 * @param numa 被除数
30 * @param na 被除数长度
31 * @warning eqsep(dst,numa), na>0
32 */
33static inline void lmmp_divexact_by3_(mp_ptr dst, mp_srcptr numa, mp_size_t na) {
34 mp_limb_t c = 0;
35 mp_limb_t l, q, s;
36 mp_size_t i = 0;
37 do {
38 s = numa[i];
39 l = s - c;
40 c = l > s;
41 q = l * MODLIMB_INVERSE_3;
42 dst[i] = q;
43 l = q + q;
44 c += l < q;
45 l += q;
46 c += l < q;
47 } while (++i < na);
48}
49
50#define MODLIMB_INVERSE_9 ((mp_limb_t)0x8E38E38E38E38E39)
51
52/**
53 * @brief 精确除以9([dst,na] = [numa,na] / 9)
54 * @param dst 结果存储位置
55 * @param numa 被除数
56 * @param na 被除数长度
57 * @warning eqsep(dst,numa), na>0
58 */
59static inline void lmmp_divexact_by9_(mp_ptr dst, mp_srcptr numa, mp_size_t na) {
60 mp_limb_t c = 0;
61 mp_limb_t l, q, s, t, carry;
62 mp_size_t i = 0;
63 do {
64 s = numa[i];
65 l = s - c;
66 c = l > s;
67 q = l * MODLIMB_INVERSE_9;
68 dst[i] = q;
69 // carry from 9*q = (q<<3) + q
70 t = q << 3;
71 carry = (q >> (LIMB_BITS - 3)) + ((t + q) < t);
72 c += carry;
73 } while (++i < na);
74}
75
76#define MODLIMB_INVERSE_15 ((mp_limb_t)0xEEEEEEEEEEEEEEEF)
77
78/**
79 * @brief 精确除以15([dst,na] = [numa,na] / 15)
80 * @param dst 结果存储位置
81 * @param numa 被除数
82 * @param na 被除数长度
83 * @warning eqsep(dst,numa), na>0
84 */
85static inline void lmmp_divexact_by15_(mp_ptr dst, mp_srcptr numa, mp_size_t na) {
86 mp_limb_t c = 0;
87 mp_limb_t l, q, s, t, carry;
88 mp_size_t i = 0;
89 do {
90 s = numa[i];
91 l = s - c;
92 c = l > s;
93 q = l * MODLIMB_INVERSE_15;
94 dst[i] = q;
95 // carry from 15*q = (q<<4) - q
96 t = q << 4;
97 carry = (q >> (LIMB_BITS - 4)) - (t < q);
98 c += carry;
99 } while (++i < na);
100}
101
102#endif // __LAMMP_DIVEXACT_H__
static void lmmp_divexact_by15_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以15([dst,na] = [numa,na] / 15)
Definition divexact.h:85
static void lmmp_divexact_by9_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以9([dst,na] = [numa,na] / 9)
Definition divexact.h:59
static void lmmp_divexact_by3_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
精确除以3([dst,na] = [numa,na] / 3)
Definition divexact.h:33
#define MODLIMB_INVERSE_9
Definition divexact.h:50
#define MODLIMB_INVERSE_3
Definition divexact.h:24
#define MODLIMB_INVERSE_15
Definition divexact.h:76
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
uint64_t mp_limb_t
Definition lmmp.h:211
#define LIMB_BITS
Definition lmmp.h:221