1use std::cmp::Ordering;
17use std::convert::TryFrom;
18use std::convert::TryInto;
19use std::ffi::{CStr, CString};
20use std::fmt;
21use std::iter::{Product, Sum};
22use std::marker::PhantomData;
23use std::mem::MaybeUninit;
24use std::ops::{
25 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
26};
27use std::str::FromStr;
28
29use libc::c_char;
30#[cfg(feature = "num-traits")]
31use num_traits::{MulAdd, MulAddAssign, One, Zero};
32
33use crate::context::{Class, Context};
34use crate::decimal::Decimal;
35use crate::decimal32::Decimal32;
36use crate::decimal64::Decimal64;
37use crate::error::ParseDecimalError;
38
39#[repr(transparent)]
59#[derive(Clone, Copy)]
60pub struct Decimal128 {
61 pub(crate) inner: decnumber_sys::decQuad,
62}
63
64impl Decimal128 {
65 pub const NAN: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
67 [
68 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c,
69 ]
70 } else {
71 [
72 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
73 ]
74 });
75
76 pub const ZERO: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
78 [
79 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
80 ]
81 } else {
82 [
83 0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
84 ]
85 });
86
87 pub const ONE: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
89 [
90 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
91 ]
92 } else {
93 [
94 0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
95 ]
96 });
97
98 const TWO_POW_32: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
100 [
101 0x7A, 0xB5, 0xAF, 0x15, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
102 ]
103 } else {
104 [
105 0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x15, 0xAF, 0xB5, 0x7A,
106 ]
107 });
108
109 pub fn from_le_bytes(mut bytes: [u8; 16]) -> Decimal128 {
111 if cfg!(target_endian = "big") {
112 bytes.reverse();
113 }
114 Decimal128::from_ne_bytes(bytes)
115 }
116
117 pub fn from_be_bytes(mut bytes: [u8; 16]) -> Decimal128 {
119 if cfg!(target_endian = "little") {
120 bytes.reverse();
121 }
122 Decimal128::from_ne_bytes(bytes)
123 }
124
125 pub const fn from_ne_bytes(bytes: [u8; 16]) -> Decimal128 {
128 Decimal128 {
129 inner: decnumber_sys::decQuad { bytes },
130 }
131 }
132
133 pub fn to_le_bytes(&self) -> [u8; 16] {
136 let mut bytes = self.to_ne_bytes();
137 if cfg!(target_endian = "big") {
138 bytes.reverse();
139 }
140 bytes
141 }
142
143 pub fn to_be_bytes(&self) -> [u8; 16] {
146 let mut bytes = self.to_ne_bytes();
147 if cfg!(target_endian = "little") {
148 bytes.reverse();
149 }
150 bytes
151 }
152
153 pub fn to_ne_bytes(&self) -> [u8; 16] {
156 self.inner.bytes
157 }
158
159 pub fn class(&self) -> Class {
161 Class::from_c(unsafe { decnumber_sys::decQuadClass(&self.inner) })
162 }
163
164 pub fn digits(&self) -> u32 {
169 unsafe { decnumber_sys::decQuadDigits(&self.inner) }
170 }
171
172 pub fn coefficient(&self) -> i128 {
176 let mut dpd = if cfg!(target_endian = "big") {
177 u128::from_be_bytes(self.inner.bytes)
178 } else {
179 u128::from_le_bytes(self.inner.bytes)
180 };
181
182 let dpd_mask = 0b11_1111_1111;
184
185 let mut dpd2bin = |include_mill: bool| -> i128 {
186 let mut r: i128 = 0;
187
188 r += i128::from(unsafe { decnumber_sys::DPD2BIN[dpd as usize & dpd_mask] });
191 dpd >>= 10;
192 r += i128::from(unsafe { decnumber_sys::DPD2BINK[dpd as usize & dpd_mask] });
193 dpd >>= 10;
194 if include_mill {
195 r += i128::from(unsafe { decnumber_sys::DPD2BINM[dpd as usize & dpd_mask] });
196 dpd >>= 10;
197 }
198
199 r
200 };
201
202 let mut r = dpd2bin(true);
204 r += dpd2bin(true) * 1_000_000_000;
206 r += dpd2bin(true) * 1_000_000_000_000_000_000;
208 r += dpd2bin(false) * 1_000_000_000_000_000_000_000_000_000;
210
211 let h = i128::from(unsafe { decnumber_sys::DECCOMBMSD[(dpd >> 12) as usize] });
213
214 if h > 0 {
215 r += h * 1_000_000_000_000_000_000_000_000_000_000_000;
216 }
217
218 if self.is_negative() {
219 r *= -1;
220 }
221
222 r
223 }
224
225 pub fn coefficient_digits(&self) -> [u8; decnumber_sys::DECQUAD_Pmax] {
230 let mut buf = [0u8; decnumber_sys::DECQUAD_Pmax];
231 unsafe {
232 decnumber_sys::decQuadGetCoefficient(&self.inner, buf.as_mut_ptr() as *mut u8);
233 }
234 buf
235 }
236
237 pub fn exponent(&self) -> i32 {
239 unsafe { decnumber_sys::decQuadGetExponent(&self.inner) }
240 }
241
242 pub fn canonical(mut self) -> Decimal128 {
245 let inner = &mut self.inner as *mut decnumber_sys::decQuad;
246 unsafe {
247 decnumber_sys::decQuadCanonical(inner, inner);
248 }
249 self
250 }
251
252 pub fn is_canonical(&self) -> bool {
254 unsafe { decnumber_sys::decQuadIsCanonical(&self.inner) != 0 }
255 }
256
257 pub fn is_finite(&self) -> bool {
261 unsafe { decnumber_sys::decQuadIsFinite(&self.inner) != 0 }
262 }
263
264 pub fn is_infinite(&self) -> bool {
266 unsafe { decnumber_sys::decQuadIsInfinite(&self.inner) != 0 }
267 }
268
269 pub fn is_integer(&self) -> bool {
274 unsafe { decnumber_sys::decQuadIsInteger(&self.inner) != 0 }
275 }
276
277 pub fn is_logical(&self) -> bool {
282 unsafe { decnumber_sys::decQuadIsInteger(&self.inner) != 0 }
283 }
284
285 pub fn is_nan(&self) -> bool {
287 unsafe { decnumber_sys::decQuadIsNaN(&self.inner) != 0 }
288 }
289
290 pub fn is_negative(&self) -> bool {
292 unsafe { decnumber_sys::decQuadIsNegative(&self.inner) != 0 }
293 }
294
295 pub fn is_normal(&self) -> bool {
299 unsafe { decnumber_sys::decQuadIsNormal(&self.inner) != 0 }
300 }
301
302 pub fn is_positive(&self) -> bool {
304 unsafe { decnumber_sys::decQuadIsPositive(&self.inner) != 0 }
305 }
306
307 pub fn is_signaling_nan(&self) -> bool {
309 unsafe { decnumber_sys::decQuadIsSignaling(&self.inner) != 0 }
310 }
311
312 pub fn is_signed(&self) -> bool {
316 unsafe { decnumber_sys::decQuadIsSigned(&self.inner) != 0 }
317 }
318
319 pub fn is_subnormal(&self) -> bool {
324 unsafe { decnumber_sys::decQuadIsSubnormal(&self.inner) != 0 }
325 }
326
327 pub fn is_zero(&self) -> bool {
329 unsafe { decnumber_sys::decQuadIsZero(&self.inner) != 0 }
330 }
331
332 pub fn quantum_matches(&self, rhs: &Decimal128) -> bool {
338 unsafe { decnumber_sys::decQuadSameQuantum(&self.inner, &rhs.inner) != 0 }
339 }
340
341 pub fn total_cmp(&self, rhs: &Decimal128) -> Ordering {
346 let mut d = Decimal128::ZERO;
347 unsafe {
348 decnumber_sys::decQuadCompareTotal(&mut d.inner, &self.inner, &rhs.inner);
349 }
350 if d.is_positive() {
351 Ordering::Greater
352 } else if d.is_negative() {
353 Ordering::Less
354 } else {
355 debug_assert!(d.is_zero());
356 Ordering::Equal
357 }
358 }
359
360 pub fn to_standard_notation_string(&self) -> String {
363 if !self.is_finite() {
364 return self.to_string();
365 }
366 let mut digits = [b'0'; decnumber_sys::DECQUAD_Pmax];
367 let mut digits_idx = 0;
368 let (sourlo, sourml, sourmh, sourhi) = if cfg!(target_endian = "little") {
369 (
370 u32::from_ne_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
371 u32::from_ne_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
372 u32::from_ne_bytes(self.inner.bytes[8..12].try_into().unwrap()) as usize,
373 u32::from_ne_bytes(self.inner.bytes[12..16].try_into().unwrap()) as usize,
374 )
375 } else {
376 (
377 u32::from_ne_bytes(self.inner.bytes[12..16].try_into().unwrap()) as usize,
378 u32::from_ne_bytes(self.inner.bytes[8..12].try_into().unwrap()) as usize,
379 u32::from_ne_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
380 u32::from_ne_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
381 )
382 };
383
384 let comb = ((sourhi >> 26) & 0x1f) as usize;
385 let msd = unsafe { decnumber_sys::DECCOMBMSD[comb] };
386
387 if msd > 0 {
388 digits[digits_idx] = b'0' + msd as u8;
389 digits_idx += 1;
390 }
391
392 #[allow(unused_assignments)]
393 let mut dpd: usize = 0;
394
395 dpd = (sourhi >> 4) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
397
398 dpd = ((sourhi & 0xf) << 6) | (sourmh >> 26); dpd2char!(dpd, digits, digits_idx);
400
401 dpd = (sourmh >> 16) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
403
404 dpd = (sourmh >> 6) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
406
407 dpd = ((sourmh & 0x3f) << 4) | (sourml >> 28); dpd2char!(dpd, digits, digits_idx);
409
410 dpd = (sourml >> 18) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
412
413 dpd = (sourml >> 8) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
415
416 dpd = ((sourml & 0xff) << 2) | (sourlo >> 30); dpd2char!(dpd, digits, digits_idx);
418
419 dpd = (sourlo >> 20) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
421
422 dpd = (sourlo >> 10) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
424
425 dpd = (sourlo) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
427
428 stringify_digits!(self, digits, digits_idx)
429 }
430}
431
432impl Default for Decimal128 {
433 fn default() -> Decimal128 {
434 Decimal128::ZERO
435 }
436}
437
438impl fmt::Debug for Decimal128 {
439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440 fmt::Display::fmt(self, f)
441 }
442}
443
444impl fmt::Display for Decimal128 {
445 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446 let mut buf = ['\0'; decnumber_sys::DECQUAD_String];
447 let c_str = unsafe {
448 if f.alternate() {
449 decnumber_sys::decQuadToEngString(&self.inner, buf.as_mut_ptr() as *mut c_char);
450 } else {
451 decnumber_sys::decQuadToString(&self.inner, buf.as_mut_ptr() as *mut c_char);
452 }
453 CStr::from_ptr(buf.as_ptr() as *const c_char)
454 };
455 f.write_str(c_str.to_str().expect("decQuadToString yields valid UTF-8"))
456 }
457}
458
459impl FromStr for Decimal128 {
460 type Err = ParseDecimalError;
461
462 fn from_str(s: &str) -> Result<Decimal128, ParseDecimalError> {
463 Context::<Decimal128>::default().parse(s)
464 }
465}
466
467impl From<i32> for Decimal128 {
468 fn from(n: i32) -> Decimal128 {
469 let mut d = Decimal128::ZERO;
470 unsafe {
471 decnumber_sys::decQuadFromInt32(&mut d.inner, n);
472 }
473 d
474 }
475}
476
477impl From<u32> for Decimal128 {
478 fn from(n: u32) -> Decimal128 {
479 let mut d = Decimal128::ZERO;
480 unsafe {
481 decnumber_sys::decQuadFromUInt32(&mut d.inner, n);
482 }
483 d
484 }
485}
486
487impl From<i64> for Decimal128 {
492 fn from(n: i64) -> Decimal128 {
493 let mut cx = Context::<Decimal128>::default();
494 let d = from_signed_int!(Decimal128, cx, n);
495 debug_assert!(!cx.status().any());
496 d
497 }
498}
499
500impl From<u64> for Decimal128 {
501 fn from(n: u64) -> Decimal128 {
502 let mut cx = Context::<Decimal128>::default();
503 let d = from_unsigned_int!(Decimal128, cx, n);
504 debug_assert!(!cx.status().any());
505 d
506 }
507}
508
509impl From<Decimal32> for Decimal128 {
510 fn from(d32: Decimal32) -> Decimal128 {
511 Decimal128::from(Decimal64::from(d32))
512 }
513}
514
515impl From<Decimal64> for Decimal128 {
516 fn from(d64: Decimal64) -> Decimal128 {
517 let mut d128 = Decimal128::ZERO;
518 unsafe {
519 decnumber_sys::decDoubleToWider(&d64.inner, &mut d128.inner);
520 }
521 d128
522 }
523}
524
525impl PartialOrd for Decimal128 {
526 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
527 Context::<Decimal128>::default().partial_cmp(*self, *other)
528 }
529}
530
531impl PartialEq for Decimal128 {
532 fn eq(&self, other: &Self) -> bool {
533 self.partial_cmp(other) == Some(Ordering::Equal)
534 }
535}
536
537impl Neg for Decimal128 {
538 type Output = Decimal128;
539
540 fn neg(self) -> Decimal128 {
541 Context::<Decimal128>::default().minus(self)
542 }
543}
544
545impl Add<Decimal128> for Decimal128 {
546 type Output = Decimal128;
547
548 fn add(self, rhs: Decimal128) -> Decimal128 {
549 Context::<Decimal128>::default().add(self, rhs)
550 }
551}
552
553impl AddAssign<Decimal128> for Decimal128 {
554 fn add_assign(&mut self, rhs: Decimal128) {
555 *self = Context::<Decimal128>::default().add(*self, rhs);
556 }
557}
558
559impl Div<Decimal128> for Decimal128 {
560 type Output = Decimal128;
561
562 fn div(self, rhs: Decimal128) -> Decimal128 {
563 Context::<Decimal128>::default().div(self, rhs)
564 }
565}
566
567impl DivAssign<Decimal128> for Decimal128 {
568 fn div_assign(&mut self, rhs: Decimal128) {
569 *self = Context::<Decimal128>::default().div(*self, rhs);
570 }
571}
572
573impl Mul<Decimal128> for Decimal128 {
574 type Output = Decimal128;
575
576 fn mul(self, rhs: Decimal128) -> Decimal128 {
577 Context::<Decimal128>::default().mul(self, rhs)
578 }
579}
580
581impl MulAssign<Decimal128> for Decimal128 {
582 fn mul_assign(&mut self, rhs: Decimal128) {
583 *self = Context::<Decimal128>::default().mul(*self, rhs);
584 }
585}
586
587impl Rem<Decimal128> for Decimal128 {
588 type Output = Decimal128;
589
590 fn rem(self, rhs: Decimal128) -> Decimal128 {
591 Context::<Decimal128>::default().rem(self, rhs)
592 }
593}
594
595impl RemAssign<Decimal128> for Decimal128 {
596 fn rem_assign(&mut self, rhs: Decimal128) {
597 *self = Context::<Decimal128>::default().rem(*self, rhs);
598 }
599}
600
601impl Sub<Decimal128> for Decimal128 {
602 type Output = Decimal128;
603
604 fn sub(self, rhs: Decimal128) -> Decimal128 {
605 Context::<Decimal128>::default().sub(self, rhs)
606 }
607}
608
609impl SubAssign<Decimal128> for Decimal128 {
610 fn sub_assign(&mut self, rhs: Decimal128) {
611 *self = Context::<Decimal128>::default().sub(*self, rhs);
612 }
613}
614
615impl Sum for Decimal128 {
616 fn sum<I>(iter: I) -> Self
617 where
618 I: Iterator<Item = Decimal128>,
619 {
620 let mut cx = Context::<Decimal128>::default();
621 let mut sum = Decimal128::ZERO;
622 for d in iter {
623 sum = cx.add(sum, d);
624 }
625 sum
626 }
627}
628
629impl<'a> Sum<&'a Decimal128> for Decimal128 {
630 fn sum<I>(iter: I) -> Self
631 where
632 I: Iterator<Item = &'a Decimal128>,
633 {
634 iter.copied().sum()
635 }
636}
637
638impl Product for Decimal128 {
639 fn product<I>(iter: I) -> Self
640 where
641 I: Iterator<Item = Decimal128>,
642 {
643 let mut cx = Context::<Decimal128>::default();
644 let mut product = Decimal128::ONE;
645 for d in iter {
646 product = cx.mul(product, d);
647 }
648 product
649 }
650}
651
652impl<'a> Product<&'a Decimal128> for Decimal128 {
653 fn product<I>(iter: I) -> Self
654 where
655 I: Iterator<Item = &'a Decimal128>,
656 {
657 iter.copied().product()
658 }
659}
660
661impl Default for Context<Decimal128> {
662 fn default() -> Context<Decimal128> {
663 let mut ctx = MaybeUninit::<decnumber_sys::decContext>::uninit();
664 let ctx = unsafe {
665 decnumber_sys::decContextDefault(ctx.as_mut_ptr(), decnumber_sys::DEC_INIT_DECQUAD);
666 ctx.assume_init()
667 };
668 Context {
669 inner: ctx,
670 _phantom: PhantomData,
671 }
672 }
673}
674
675impl Context<Decimal128> {
676 pub fn parse<S>(&mut self, s: S) -> Result<Decimal128, ParseDecimalError>
678 where
679 S: Into<Vec<u8>>,
680 {
681 let c_string = CString::new(s).map_err(|_| ParseDecimalError)?;
682 let mut d = Decimal128::ZERO;
683 unsafe {
684 decnumber_sys::decQuadFromString(&mut d.inner, c_string.as_ptr(), &mut self.inner);
685 }
686 if (self.inner.status & decnumber_sys::DEC_Conversion_syntax) != 0 {
687 Err(ParseDecimalError)
688 } else {
689 Ok(d)
690 }
691 }
692
693 pub fn from_decimal<const N: usize>(&mut self, d: &Decimal<N>) -> Decimal128 {
698 let mut d128 = Decimal128::ZERO;
699 unsafe {
700 decnumber_sys::decimal128FromNumber(&mut d128.inner, d.as_ptr(), &mut self.inner);
701 }
702 d128
703 }
704
705 pub fn from_i128(&mut self, n: i128) -> Decimal128 {
732 from_signed_int!(Decimal128, self, n)
733 }
734
735 pub fn from_u128(&mut self, n: u128) -> Decimal128 {
757 from_unsigned_int!(Decimal128, self, n)
758 }
759
760 pub fn abs(&mut self, mut n: Decimal128) -> Decimal128 {
768 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
769 unsafe {
770 decnumber_sys::decQuadAbs(n_inner, n_inner, &mut self.inner);
771 }
772 n
773 }
774
775 pub fn add(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
777 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
778 unsafe {
779 decnumber_sys::decQuadAdd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
780 }
781 lhs
782 }
783
784 pub fn and(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
789 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
790 unsafe {
791 decnumber_sys::decQuadAnd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
792 }
793 lhs
794 }
795
796 pub fn div(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
798 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
799 unsafe {
800 decnumber_sys::decQuadDivide(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
801 }
802 lhs
803 }
804
805 pub fn div_integer(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
813 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
814 unsafe {
815 decnumber_sys::decQuadDivideInteger(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
816 }
817 lhs
818 }
819
820 pub fn fma(&mut self, mut x: Decimal128, y: Decimal128, z: Decimal128) -> Decimal128 {
825 let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
826 unsafe {
827 decnumber_sys::decQuadFMA(x_inner, x_inner, &y.inner, &z.inner, &mut self.inner);
828 }
829 x
830 }
831
832 pub fn invert(&mut self, mut n: Decimal128) -> Decimal128 {
837 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
838 unsafe {
839 decnumber_sys::decQuadInvert(n_inner, n_inner, &mut self.inner);
840 }
841 n
842 }
843
844 pub fn logb(&mut self, mut n: Decimal128) -> Decimal128 {
847 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
848 unsafe {
849 decnumber_sys::decQuadLogB(n_inner, n_inner, &mut self.inner);
850 }
851 n
852 }
853
854 pub fn max(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
859 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
860 unsafe {
861 decnumber_sys::decQuadMax(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
862 }
863 lhs
864 }
865
866 pub fn max_abs(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
868 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
869 unsafe {
870 decnumber_sys::decQuadMaxMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
871 }
872 lhs
873 }
874
875 pub fn min(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
880 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
881
882 unsafe {
883 decnumber_sys::decQuadMin(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
884 }
885 lhs
886 }
887
888 pub fn min_abs(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
890 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
891 unsafe {
892 decnumber_sys::decQuadMinMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
893 }
894 lhs
895 }
896
897 pub fn minus(&mut self, mut n: Decimal128) -> Decimal128 {
899 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
900 unsafe {
901 decnumber_sys::decQuadMinus(n_inner, n_inner, &mut self.inner);
902 }
903 n
904 }
905
906 pub fn mul(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
908 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
909 unsafe {
910 decnumber_sys::decQuadMultiply(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
911 }
912 lhs
913 }
914
915 pub fn next_minus(&mut self, mut n: Decimal128) -> Decimal128 {
919 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
920 unsafe {
921 decnumber_sys::decQuadNextMinus(n_inner, n_inner, &mut self.inner);
922 }
923 n
924 }
925
926 pub fn next_plus(&mut self, mut n: Decimal128) -> Decimal128 {
930 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
931 unsafe {
932 decnumber_sys::decQuadNextPlus(n_inner, n_inner, &mut self.inner);
933 }
934 n
935 }
936
937 pub fn next_toward(&mut self, mut x: Decimal128, y: Decimal128) -> Decimal128 {
941 let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
942 unsafe {
943 decnumber_sys::decQuadNextToward(x_inner, x_inner, &y.inner, &mut self.inner);
944 }
945 x
946 }
947
948 pub fn partial_cmp(&mut self, lhs: Decimal128, rhs: Decimal128) -> Option<Ordering> {
954 let mut d = Decimal128::ZERO;
955 unsafe {
956 decnumber_sys::decQuadCompare(&mut d.inner, &lhs.inner, &rhs.inner, &mut self.inner);
957 }
958 if d.is_positive() {
959 Some(Ordering::Greater)
960 } else if d.is_negative() {
961 Some(Ordering::Less)
962 } else if d.is_zero() {
963 Some(Ordering::Equal)
964 } else {
965 debug_assert!(d.is_nan());
966 None
967 }
968 }
969
970 pub fn plus(&mut self, mut n: Decimal128) -> Decimal128 {
972 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
973 unsafe {
974 decnumber_sys::decQuadPlus(n_inner, n_inner, &mut self.inner);
975 }
976 n
977 }
978
979 pub fn quantize(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
981 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
982 unsafe {
983 decnumber_sys::decQuadQuantize(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
984 }
985 lhs
986 }
987
988 pub fn reduce(&mut self, mut n: Decimal128) -> Decimal128 {
994 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
995 unsafe {
996 decnumber_sys::decQuadReduce(n_inner, n_inner, &mut self.inner);
997 }
998 n
999 }
1000
1001 pub fn rem(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1004 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1005 unsafe {
1006 decnumber_sys::decQuadRemainder(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1007 }
1008 lhs
1009 }
1010
1011 pub fn rem_near(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1014 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1015 unsafe {
1016 decnumber_sys::decQuadRemainderNear(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1017 }
1018 lhs
1019 }
1020
1021 pub fn rotate(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1031 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1032 unsafe {
1033 decnumber_sys::decQuadRotate(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1034 }
1035 lhs
1036 }
1037
1038 pub fn round(&mut self, mut n: Decimal128) -> Decimal128 {
1041 let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
1042 unsafe {
1043 decnumber_sys::decQuadToIntegralExact(n_inner, n_inner, &mut self.inner);
1044 }
1045 n
1046 }
1047
1048 pub fn scaleb(&mut self, mut x: Decimal128, y: Decimal128) -> Decimal128 {
1050 let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
1051 unsafe {
1052 decnumber_sys::decQuadScaleB(x_inner, x_inner, &y.inner, &mut self.inner);
1053 }
1054 x
1055 }
1056
1057 pub fn set_exponent(&mut self, d: &mut Decimal128, e: i32) {
1059 unsafe {
1060 decnumber_sys::decQuadSetExponent(&mut d.inner, &mut self.inner, e);
1061 }
1062 }
1063
1064 pub fn shift(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1074 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1075 unsafe {
1076 decnumber_sys::decQuadShift(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1077 }
1078 lhs
1079 }
1080
1081 pub fn rescale(&mut self, x: &mut Decimal128, s: i32) {
1111 let e = x.exponent();
1112 *x = self.shift(*x, Decimal128::from(e - s));
1113 self.set_exponent(x, s);
1114 }
1115
1116 pub fn sub(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1118 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1119 unsafe {
1120 decnumber_sys::decQuadSubtract(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1121 }
1122 lhs
1123 }
1124
1125 pub fn or(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1130 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1131 unsafe {
1132 decnumber_sys::decQuadOr(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1133 }
1134 lhs
1135 }
1136
1137 pub fn xor(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1142 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1143 unsafe {
1144 decnumber_sys::decQuadXor(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1145 }
1146 lhs
1147 }
1148}
1149
1150#[cfg(feature = "num-traits")]
1151impl One for Decimal128 {
1152 #[inline]
1153 fn one() -> Self {
1154 Self::ONE
1155 }
1156}
1157
1158#[cfg(feature = "num-traits")]
1159impl Zero for Decimal128 {
1160 #[inline]
1161 fn zero() -> Self {
1162 Self::ZERO
1163 }
1164
1165 #[inline]
1166 fn is_zero(&self) -> bool {
1167 self.is_zero()
1168 }
1169}
1170
1171#[cfg(feature = "num-traits")]
1172impl MulAdd for Decimal128 {
1173 type Output = Self;
1174
1175 fn mul_add(self, a: Self, b: Self) -> Self::Output {
1176 Context::<Self>::default().fma(self, a, b)
1177 }
1178}
1179
1180#[cfg(feature = "num-traits")]
1181impl MulAddAssign for Decimal128 {
1182 #[inline]
1183 fn mul_add_assign(&mut self, a: Self, b: Self) {
1184 *self = self.mul_add(a, b)
1185 }
1186}