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