1use dfp_number_sys::bid128_000::*;
4use dfp_number_sys::*;
5use std::cmp::Ordering;
6use std::convert::Infallible;
7use std::fmt;
8use std::fmt::{Debug, Display};
9use std::str::FromStr;
10
11#[macro_export]
12macro_rules! decnum {
13 ($e:expr) => {{
14 Decimal128::from(stringify!($e))
15 }};
16}
17
18#[derive(Copy, Clone)]
20pub struct Decimal128(BID128);
21
22impl Default for Decimal128 {
23 fn default() -> Self {
25 Self::zero()
26 }
27}
28
29impl Debug for Decimal128 {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 let mut flags = EXE_CLEAR;
33 write!(f, "{}", bid128_to_string(self.0, &mut flags))
34 }
35}
36
37impl Display for Decimal128 {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 let mut flags = EXE_CLEAR;
41 let s = bid128_to_string(self.0, &mut flags);
42 let negative = s.starts_with('-');
43 let mut split = s[1..].split('E');
44 if let Some((sb, sa)) = split.next().zip(split.next()) {
45 if let Ok(exponent) = sa.parse::<isize>() {
46 let decimal_points = exponent.unsigned_abs();
47 let (mut before, mut after) = if exponent < 0 {
48 let digit_count = sb.len();
49 if digit_count <= decimal_points {
50 let before = "0".to_string();
51 let mut after = "0".repeat(decimal_points - digit_count);
52 after.push_str(sb.trim_end_matches('0'));
53 (before, after)
54 } else {
55 let before = sb[..digit_count - decimal_points].to_string();
56 let after = sb[digit_count - decimal_points..].trim_end_matches('0').to_string();
57 (before, after)
58 }
59 } else {
60 let mut before = sb.to_string();
61 before.push_str(&"0".repeat(decimal_points));
62 let after = "".to_string();
63 (before, after)
64 };
65 if let Some(precision) = f.precision() {
66 if after.len() < precision {
67 after.push_str(&"0".repeat(precision - after.len()));
68 } else {
69 after = after[0..precision].to_string();
70 }
71 }
72 if !after.is_empty() {
73 before.push('.');
74 before.push_str(&after);
75 }
76 return f.pad_integral(!negative, "", &before);
77 }
78 }
79 f.pad(&s)
80 }
81}
82
83impl Decimal128 {
84 pub fn new(n: i64, s: i32) -> Self {
85 Self(bid128_scalbn(bid128_from_int64(n), -s))
86 }
87
88 pub fn zero() -> Self {
89 Self(bid128_from_uint32(0))
90 }
91
92 pub fn is_zero(&self) -> bool {
93 bid128_is_zero(self.0)
94 }
95
96 pub fn one() -> Self {
97 Self(bid128_from_uint32(1))
98 }
99
100 pub fn two() -> Self {
101 Self(bid128_from_uint32(2))
102 }
103
104 pub fn ten() -> Self {
105 Self(bid128_from_uint32(10))
106 }
107
108 pub fn one_hundred() -> Self {
109 Self(bid128_from_uint32(100))
110 }
111
112 pub fn one_thousand() -> Self {
113 Self(bid128_from_uint32(1000))
114 }
115
116 pub fn ln(&self) -> Decimal128 {
117 let mut flags = EXE_CLEAR;
118 Self(bid128_log(self.0, RND_NEAREST_EVEN, &mut flags))
119 }
120
121 pub fn exp(&self) -> Decimal128 {
122 let mut flags = EXE_CLEAR;
123 Self(bid128_exp(self.0, RND_NEAREST_EVEN, &mut flags))
124 }
125
126 pub fn round_dp(&self, dp: i32) -> Self {
127 let q = bid128_scalbn(Self::one().0, -dp);
128 let mut flags = EXE_CLEAR;
129 Self(bid128_quantize(self.0, q, RND_NEAREST_EVEN, &mut flags))
130 }
131}
132
133impl std::ops::Neg for Decimal128 {
134 type Output = Self;
135 fn neg(self) -> Self::Output {
136 Self(bid128_negate(self.0))
137 }
138}
139
140impl std::ops::Add<Self> for Decimal128 {
141 type Output = Self;
142
143 fn add(self, rhs: Self) -> Self::Output {
144 let mut flags = EXE_CLEAR;
145 Self(bid128_add(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags))
146 }
147}
148
149impl std::ops::AddAssign<Self> for Decimal128 {
150 fn add_assign(&mut self, rhs: Self) {
151 let mut flags = EXE_CLEAR;
152 self.0 = bid128_add(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags)
153 }
154}
155
156impl std::ops::Sub<Self> for Decimal128 {
157 type Output = Self;
158
159 fn sub(self, rhs: Self) -> Self::Output {
160 let mut flags = EXE_CLEAR;
161 Self(bid128_sub(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags))
162 }
163}
164
165impl std::ops::SubAssign<Self> for Decimal128 {
166 fn sub_assign(&mut self, rhs: Self) {
167 let mut flags = EXE_CLEAR;
168 self.0 = bid128_sub(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags)
169 }
170}
171
172impl std::ops::Mul<Self> for Decimal128 {
173 type Output = Self;
174
175 fn mul(self, rhs: Self) -> Self::Output {
176 let mut flags = EXE_CLEAR;
177 Self(bid128_mul(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags))
178 }
179}
180
181impl std::ops::MulAssign<Self> for Decimal128 {
182 fn mul_assign(&mut self, rhs: Self) {
183 let mut flags = EXE_CLEAR;
184 self.0 = bid128_mul(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags)
185 }
186}
187
188impl std::ops::Div<Self> for Decimal128 {
189 type Output = Self;
190
191 fn div(self, rhs: Self) -> Self::Output {
192 let mut flags = EXE_CLEAR;
193 Self(bid128_div(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags))
194 }
195}
196
197impl std::ops::DivAssign<Self> for Decimal128 {
198 fn div_assign(&mut self, rhs: Self) {
199 let mut flags = EXE_CLEAR;
200 self.0 = bid128_div(self.0, rhs.0, RND_NEAREST_EVEN, &mut flags)
201 }
202}
203
204impl PartialEq<Self> for Decimal128 {
205 fn eq(&self, rhs: &Self) -> bool {
206 let mut flags = EXE_CLEAR;
207 bid128_quiet_equal(self.0, rhs.0, &mut flags)
208 }
209}
210
211impl Eq for Decimal128 {}
212
213impl PartialOrd<Self> for Decimal128 {
214 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
215 Some(self.cmp(rhs))
216 }
217
218 fn lt(&self, rhs: &Self) -> bool {
219 let mut flags = EXE_CLEAR;
220 bid128_quiet_less(self.0, rhs.0, &mut flags)
221 }
222
223 fn le(&self, rhs: &Self) -> bool {
224 let mut flags = EXE_CLEAR;
225 bid128_quiet_less_equal(self.0, rhs.0, &mut flags)
226 }
227
228 fn gt(&self, rhs: &Self) -> bool {
229 let mut flags = EXE_CLEAR;
230 bid128_quiet_greater(self.0, rhs.0, &mut flags)
231 }
232
233 fn ge(&self, rhs: &Self) -> bool {
234 let mut flags = EXE_CLEAR;
235 bid128_quiet_greater_equal(self.0, rhs.0, &mut flags)
236 }
237}
238
239impl Ord for Decimal128 {
240 fn cmp(&self, rhs: &Self) -> Ordering {
241 let mut flags = EXE_CLEAR;
242 if bid128_quiet_equal(self.0, rhs.0, &mut flags) {
243 return Ordering::Equal;
244 }
245 flags = EXE_CLEAR;
246 if bid128_quiet_less(self.0, rhs.0, &mut flags) {
247 return Ordering::Less;
248 }
249 Ordering::Greater
250 }
251
252 fn max(self, rhs: Self) -> Self
253 where
254 Self: Sized,
255 {
256 let mut flags = EXE_CLEAR;
257 Self(bid128_min_num(self.0, rhs.0, &mut flags))
258 }
259
260 fn min(self, rhs: Self) -> Self
261 where
262 Self: Sized,
263 {
264 let mut flags = EXE_CLEAR;
265 Self(bid128_min_num(self.0, rhs.0, &mut flags))
266 }
267}
268
269impl From<&str> for Decimal128 {
270 fn from(s: &str) -> Self {
272 let mut flags = EXE_CLEAR;
273 Self(bid128_from_string(s, RND_NEAREST_EVEN, &mut flags))
274 }
275}
276
277impl FromStr for Decimal128 {
278 type Err = Infallible;
279 fn from_str(s: &str) -> Result<Self, Self::Err> {
281 Ok(s.into())
282 }
283}
284
285impl From<u8> for Decimal128 {
286 fn from(n: u8) -> Self {
288 Self(bid128_from_uint32(n as u32))
289 }
290}
291
292impl From<i8> for Decimal128 {
293 fn from(n: i8) -> Self {
295 Self(bid128_from_int32(n as i32))
296 }
297}
298
299impl From<u16> for Decimal128 {
300 fn from(n: u16) -> Self {
302 Self(bid128_from_uint32(n as u32))
303 }
304}
305
306impl From<i16> for Decimal128 {
307 fn from(n: i16) -> Self {
309 Self(bid128_from_int32(n as i32))
310 }
311}
312
313impl From<u32> for Decimal128 {
314 fn from(n: u32) -> Self {
316 Self(bid128_from_uint32(n))
317 }
318}
319
320impl From<i32> for Decimal128 {
321 fn from(n: i32) -> Self {
323 Self(bid128_from_int32(n))
324 }
325}
326
327impl From<u64> for Decimal128 {
328 fn from(n: u64) -> Self {
330 Self(bid128_from_uint64(n))
331 }
332}
333
334impl From<i64> for Decimal128 {
335 fn from(n: i64) -> Self {
337 Self(bid128_from_int64(n))
338 }
339}
340
341impl From<usize> for Decimal128 {
342 fn from(n: usize) -> Self {
344 Self(bid128_from_uint64(n as u64))
345 }
346}
347
348impl From<isize> for Decimal128 {
349 fn from(n: isize) -> Self {
351 Self(bid128_from_int64(n as i64))
352 }
353}