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