LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
signed.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_SIGNED_H__
20#define __LAMMP_SIGNED_H__
21
22#include "../lmmpn.h"
23
24#ifndef INLINE_
25#define INLINE_ static inline
26#endif
27
28/**
29 * @brief 计算带符号数的加法
30 * @param dst 结果指针,自行保证有足够的空间,需要的最多的空间为max(abs(na),abs(nb)) + 1
31 * @param numa 第一个数的指针
32 * @param na 第一个数的长度,为负数表示此数为负数,绝对值表示实际长度
33 * @param numb 第二个数的指针
34 * @param nb 第二个数的长度,为负数表示此数为负数,绝对值表示实际长度
35 * @return 结果的长度,为负数表示此数为负数,绝对值表示实际长度
36 * @warning dst!=NULL, eqsep(dst,[numa|numb])
37 */
39 if (na == 0 && nb != 0) {
40 lmmp_copy(dst, numb, LMMP_ABS(nb));
41 return nb;
42 } else if (na != 0 && nb == 0) {
43 lmmp_copy(dst, numa, LMMP_ABS(na));
44 return na;
45 } else if (na == 0 && nb == 0) {
46 dst[0] = 0;
47 return 0;
48 } else if (na < 0 && nb < 0) {
49 na = -na;
50 nb = -nb;
51 if (na > nb) {
52 dst[na] = lmmp_add_(dst, numa, na, numb, nb);
53 return dst[na] == 0 ? -na : -(na + 1);
54 } else {
55 dst[nb] = lmmp_add_(dst, numb, nb, numa, na);
56 return dst[nb] == 0 ? -nb : -(nb + 1);
57 }
58 } else if (na > 0 && nb > 0) {
59 if (na > nb) {
60 dst[na] = lmmp_add_(dst, numa, na, numb, nb);
61 return dst[na] == 0 ? na : na + 1;
62 } else {
63 dst[nb] = lmmp_add_(dst, numb, nb, numa, na);
64 return dst[nb] == 0 ? nb : nb + 1;
65 }
66 } else if (na < 0 && nb > 0) {
67 na = -na;
68 if (na < nb) {
69 lmmp_sub_(dst, numb, nb, numa, na);
70 while (dst[nb - 1] == 0 && nb > 0) {
71 --nb;
72 }
73 return nb;
74 } else if (na > nb) {
75 lmmp_sub_(dst, numa, na, numb, nb);
76 while (dst[na - 1] == 0 && na > 0) {
77 --na;
78 }
79 return -na;
80 } else {
81 int cmp = lmmp_cmp_(numa, numb, na);
82 if (cmp < 0) {
83 lmmp_sub_(dst, numb, nb, numa, na);
84 while (dst[nb - 1] == 0 && nb > 0) {
85 --nb;
86 }
87 return nb;
88 } else if (cmp > 0) {
89 lmmp_sub_(dst, numa, na, numb, nb);
90 while (dst[na - 1] == 0 && na > 0) {
91 --na;
92 }
93 return -na;
94 } else {
95 dst[0] = 0;
96 return 0;
97 }
98 }
99 } else {
100 /* na > 0 && nb < 0 */
101 nb = -nb;
102 if (na < nb) {
103 lmmp_sub_(dst, numb, nb, numa, na);
104 while (dst[nb - 1] == 0 && nb > 0) {
105 --nb;
106 }
107 return -nb;
108 } else if (na > nb) {
109 lmmp_sub_(dst, numa, na, numb, nb);
110 while (dst[na - 1] == 0 && na > 0) {
111 --na;
112 }
113 return na;
114 } else {
115 int cmp = lmmp_cmp_(numa, numb, na);
116 if (cmp < 0) {
117 lmmp_sub_(dst, numb, nb, numa, na);
118 while (dst[nb - 1] == 0 && nb > 0) {
119 --nb;
120 }
121 return -nb;
122 } else if (cmp > 0) {
123 lmmp_sub_(dst, numa, na, numb, nb);
124 while (dst[na - 1] == 0 && na > 0) {
125 --na;
126 }
127 return na;
128 } else {
129 dst[0] = 0;
130 return 0;
131 }
132 }
133 }
134}
135
136/**
137 * @brief 计算带符号数的乘法
138 * @param dst 结果指针,自行保证有足够的空间,需要空间为abs(na)+abs(nb)
139 * @param numa 第一个数的指针
140 * @param na 第一个数的长度,为负数表示此数为负数,绝对值表示实际长度
141 * @param numb 第二个数的指针
142 * @param nb 第二个数的长度,为负数表示此数为负数,绝对值表示实际长度
143 * @return 结果的长度,为负数表示此数为负数,绝对值表示实际长度
144 * @warning dst!=NULL, sep(dst,[numa|numb])
145 */
147 mp_ssize_t sign = ((na > 0) ^ (nb > 0)) ? -1 : 1;
148 na = LMMP_ABS(na);
149 nb = LMMP_ABS(nb);
150 if (na == 0 || nb == 0) {
151 dst[0] = 0;
152 return 0;
153 }
154 if (na < nb)
155 lmmp_mul_(dst, numb, nb, numa, na);
156 else
157 lmmp_mul_(dst, numa, na, numb, nb);
158 na += nb;
159 na -= (dst[na - 1] == 0);
160 return sign * na;
161}
162
163/**
164 * @brief 计算带符号数的平方
165 * @param dst 结果指针,自行保证有足够的空间,需要空间为abs(na)*2
166 * @param numa 第一个数的指针
167 * @param na 第一个数的长度,为负数表示此数为负数,绝对值表示实际长度
168 * @return 结果的长度,平方一定为非负数
169 * @warning dst!=NULL, sep(dst,numa)
170 */
172 if (na < 0) {
173 na = -na;
174 } else if (na == 0) {
175 dst[0] = 0;
176 return 0;
177 }
178 lmmp_sqr_(dst, numa, na);
179 na <<= 1;
180 na -= (dst[na - 1] == 0) ? 1 : 0;
181 return na;
182}
183
184#ifdef INLINE_
185#undef INLINE_
186#endif
187
188#endif /* __LAMMP_SIGNED_H__ */
mp_limb_t * mp_ptr
Definition lmmp.h:215
#define lmmp_copy(dst, src, n)
Definition lmmp.h:364
const mp_limb_t * mp_srcptr
Definition lmmp.h:216
int64_t mp_ssize_t
Definition lmmp.h:214
#define LMMP_ABS(x)
Definition lmmp.h:346
static mp_limb_t lmmp_add_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数加法静态内联函数 [dst,na]=[numa,na]+[numb,nb]
Definition lmmpn.h:1058
static int lmmp_cmp_(mp_srcptr numa, mp_srcptr numb, mp_size_t n)
大数比较函数(内联)
Definition lmmpn.h:1004
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]
void lmmp_sqr_(mp_ptr dst, mp_srcptr numa, mp_size_t na)
大数平方操作 [dst,2*na] = [numa,na]^2
Definition sqr.c:10
static mp_limb_t lmmp_sub_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
大数减法静态内联函数 [dst,na]=[numa,na]-[numb,nb]
Definition lmmpn.h:1072
static mp_ssize_t lmmp_sqr_signed_(mp_ptr dst, mp_srcptr numa, mp_ssize_t na)
计算带符号数的平方
Definition signed.h:171
#define INLINE_
Definition signed.h:25
static mp_ssize_t lmmp_add_signed_(mp_ptr dst, mp_srcptr numa, mp_ssize_t na, mp_srcptr numb, mp_ssize_t nb)
计算带符号数的加法
Definition signed.h:38
static mp_ssize_t lmmp_mul_signed_(mp_ptr dst, mp_srcptr numa, mp_ssize_t na, mp_srcptr numb, mp_ssize_t nb)
计算带符号数的乘法
Definition signed.h:146