1use std::cmp::Ordering;
17use std::convert::{TryFrom, TryInto};
18use std::ffi::{CStr, CString};
19use std::fmt;
20use std::iter::{Product, Sum};
21use std::marker::PhantomData;
22use std::mem::MaybeUninit;
23use std::ops::{
24 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
25};
26use std::str::FromStr;
27
28use libc::c_char;
29#[cfg(feature = "num-traits")]
30use num_traits::{MulAdd, MulAddAssign, Pow, Zero};
31#[cfg(feature = "serde")]
32use serde::{Deserialize, Serialize};
33
34use crate::context::{Class, Context};
35use crate::decimal128::Decimal128;
36use crate::decimal32::Decimal32;
37use crate::decimal64::Decimal64;
38use crate::error::{
39 FromBcdError, InvalidCoefficientError, InvalidExponentError, InvalidPrecisionError,
40 ParseDecimalError, TryFromDecimalError, TryIntoDecimalError,
41};
42
43fn validate_n(n: usize) {
44 if n < 12 || n > 999_999_999 {
46 panic!("Decimal<N>:: N is not in the range [12, 999999999]");
47 }
48}
49
50#[repr(C)]
66#[derive(Clone, Copy)]
67#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68pub struct Decimal<const N: usize> {
69 pub(crate) digits: u32,
70 pub(crate) exponent: i32,
71 pub(crate) bits: u8,
72 #[cfg_attr(feature = "serde", serde(with = "lsu_serde"))]
76 pub(crate) lsu: [u16; N],
77}
78
79#[cfg(feature = "serde")]
80pub mod serde_decimal_from_non_float_primitives {
106 use std::convert::TryFrom;
107 use std::fmt;
108 use std::str::FromStr;
109
110 use serde::de::{self, MapAccess, SeqAccess, Visitor};
111 use serde::{Deserialize, Deserializer, Serialize};
112
113 use crate::Decimal;
114
115 pub fn serialize<S, const N: usize>(d: &Decimal<N>, serializer: S) -> Result<S::Ok, S::Error>
117 where
118 S: serde::Serializer,
119 Decimal<N>: Serialize,
120 {
121 Decimal::<N>::serialize(d, serializer)
122 }
123
124 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<Decimal<N>, D::Error>
127 where
128 D: serde::Deserializer<'de>,
129 {
130 enum Field {
131 Digits,
132 Exponent,
133 Bits,
134 Lsu,
135 }
136
137 impl<'de> Deserialize<'de> for Field {
138 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
139 where
140 D: Deserializer<'de>,
141 {
142 struct FieldVisitor;
143
144 impl<'de> Visitor<'de> for FieldVisitor {
145 type Value = Field;
146
147 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
148 formatter.write_str("`digits`, `exponent`, `bits`, or `lsu`")
149 }
150
151 fn visit_str<E>(self, value: &str) -> Result<Field, E>
152 where
153 E: de::Error,
154 {
155 match value {
156 "digits" => Ok(Field::Digits),
157 "exponent" => Ok(Field::Exponent),
158 "bits" => Ok(Field::Bits),
159 "lsu" => Ok(Field::Lsu),
160 _ => Err(de::Error::unknown_field(value, FIELDS)),
161 }
162 }
163 }
164
165 deserializer.deserialize_identifier(FieldVisitor)
166 }
167 }
168
169 struct DecimalVisitor<const N: usize>;
170
171 macro_rules! deser_try_from {
172 ($($t:ty),*) => {
173 $(
174 paste::paste! {
175 fn [< visit_ $t >]<E>(self, value: $t) -> Result<Self::Value, E>
176 where
177 E: de::Error,
178 {
179 Decimal::try_from(value).map_err(serde::de::Error::custom)
180 }
181 }
182 )*
183 };
184 }
185
186 impl<'de, const N: usize> Visitor<'de> for DecimalVisitor<N> {
187 type Value = Decimal<N>;
188
189 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
190 formatter.write_str("struct Decimal or compatible primitive")
191 }
192
193 deser_try_from!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
194
195 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
196 where
197 E: de::Error,
198 {
199 Decimal::from_str(v).map_err(serde::de::Error::custom)
200 }
201
202 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
203 where
204 E: de::Error,
205 {
206 Decimal::from_str(&v).map_err(serde::de::Error::custom)
207 }
208
209 fn visit_seq<V>(self, mut seq: V) -> Result<Decimal<N>, V::Error>
210 where
211 V: SeqAccess<'de>,
212 {
213 let digits = seq
214 .next_element()?
215 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
216 let exponent = seq
217 .next_element()?
218 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
219 let bits = seq
220 .next_element()?
221 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
222
223 let lsu: Vec<u16> = seq
224 .next_element()?
225 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
226 let lsu = super::lsu_serde::check_deserialized_vec(lsu)?;
227
228 Ok(Decimal {
229 digits,
230 exponent,
231 bits,
232 lsu,
233 })
234 }
235
236 fn visit_map<V>(self, mut map: V) -> Result<Decimal<N>, V::Error>
237 where
238 V: MapAccess<'de>,
239 {
240 let mut digits = None;
241 let mut exponent = None;
242 let mut bits = None;
243 let mut lsu = None;
244 while let Some(key) = map.next_key()? {
245 match key {
246 Field::Digits => {
247 if digits.is_some() {
248 return Err(de::Error::duplicate_field("digits"));
249 }
250 digits = Some(map.next_value()?);
251 }
252 Field::Exponent => {
253 if exponent.is_some() {
254 return Err(de::Error::duplicate_field("exponent"));
255 }
256 exponent = Some(map.next_value()?);
257 }
258 Field::Bits => {
259 if bits.is_some() {
260 return Err(de::Error::duplicate_field("bits"));
261 }
262 bits = Some(map.next_value()?);
263 }
264 Field::Lsu => {
265 if lsu.is_some() {
266 return Err(de::Error::duplicate_field("lsu"));
267 }
268 let lsu_deserialized: Vec<u16> = map.next_value()?;
269 let lsu_deserialized =
270 super::lsu_serde::check_deserialized_vec(lsu_deserialized)?;
271
272 lsu = Some(lsu_deserialized);
273 }
274 }
275 }
276 let digits = digits.ok_or_else(|| de::Error::missing_field("digits"))?;
277 let exponent = exponent.ok_or_else(|| de::Error::missing_field("exponent"))?;
278 let bits = bits.ok_or_else(|| de::Error::missing_field("bits"))?;
279 let lsu = lsu.ok_or_else(|| de::Error::missing_field("lsu"))?;
280
281 Ok(Decimal {
282 digits,
283 exponent,
284 bits,
285 lsu,
286 })
287 }
288 }
289
290 const FIELDS: &'static [&'static str] = &["digits", "exponent", "bits", "lsu"];
291 deserializer.deserialize_any(DecimalVisitor)
292 }
293}
294
295#[cfg(feature = "serde")]
296mod lsu_serde {
297 use std::convert::TryInto;
298
299 use serde::de::{Error, Unexpected};
300 use serde::ser::SerializeSeq;
301 use serde::Deserialize;
302 pub fn serialize<S, const N: usize>(v: &[u16; N], serializer: S) -> Result<S::Ok, S::Error>
303 where
304 S: serde::Serializer,
305 {
306 let mut seq = serializer.serialize_seq(Some(N))?;
307 for e in v.iter() {
308 seq.serialize_element(e)?;
309 }
310 seq.end()
311 }
312
313 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<[u16; N], D::Error>
314 where
315 D: serde::Deserializer<'de>,
316 {
317 let lsu = Vec::<u16>::deserialize(deserializer)?;
318 check_deserialized_vec(lsu)
319 }
320
321 pub fn check_deserialized_vec<const N: usize, E>(lsu: Vec<u16>) -> Result<[u16; N], E>
323 where
324 E: Error,
325 {
326 lsu.try_into().map_err(|e: Vec<u16>| {
327 Error::invalid_value(
328 Unexpected::Other(&format!("&[u16] of length {}", e.len())),
329 &format!("&[u16] of length {}", N).as_str(),
330 )
331 })
332 }
333}
334
335impl<const N: usize> Decimal<N> {
336 pub(crate) fn as_ptr(&self) -> *const decnumber_sys::decNumber {
337 self as *const Decimal<N> as *const decnumber_sys::decNumber
338 }
339
340 pub(crate) fn as_mut_ptr(&mut self) -> *mut decnumber_sys::decNumber {
341 self as *mut Decimal<N> as *mut decnumber_sys::decNumber
342 }
343
344 pub fn zero() -> Decimal<N> {
347 Decimal::default()
348 }
349
350 pub fn infinity() -> Decimal<N> {
352 let mut d = Decimal::default();
353 d.bits = decnumber_sys::DECINF;
354 d
355 }
356
357 pub fn nan() -> Decimal<N> {
359 let mut d = Decimal::default();
360 d.bits = decnumber_sys::DECNAN;
361 d
362 }
363
364 fn two_pow_32() -> Decimal<N> {
367 let mut d = Decimal::default();
368 d.digits = 10;
369 d.lsu[0..4].copy_from_slice(&[296, 967, 294, 4]);
370 d
371 }
372
373 pub fn digits(&self) -> u32 {
378 self.digits
379 }
380
381 pub fn coefficient_digits(&self) -> Vec<u8> {
386 let mut buf = vec![0; usize::try_from(self.digits()).unwrap()];
387 unsafe {
388 decnumber_sys::decNumberGetBCD(self.as_ptr(), buf.as_mut_ptr() as *mut u8);
389 };
390 buf
391 }
392
393 pub fn coefficient_units(&self) -> &[u16] {
401 let units_len = Self::digits_to_lsu_elements_len(self.digits);
402 &self.lsu[0..units_len]
403 }
404
405 pub fn coefficient<T>(&mut self) -> Result<T, InvalidCoefficientError>
409 where
410 T: TryFrom<Decimal<N>>,
411 {
412 let cur_exp = self.exponent();
414 self.set_exponent(0);
417 let coefficient = <T>::try_from(*self);
418 self.set_exponent(cur_exp);
420 match coefficient {
421 Ok(d) => Ok(d),
422 Err(_) => Err(InvalidCoefficientError),
423 }
424 }
425
426 pub fn digits_to_lsu_elements_len(digits: u32) -> usize {
432 (usize::try_from(digits).unwrap() + decnumber_sys::DECDPUN - 1) / decnumber_sys::DECDPUN
433 }
434
435 pub fn exponent(&self) -> i32 {
437 self.exponent
438 }
439
440 pub fn set_exponent(&mut self, exponent: i32) {
442 self.exponent = exponent;
443 }
444
445 pub fn is_finite(&self) -> bool {
449 (self.bits & decnumber_sys::DECSPECIAL) == 0
450 }
451
452 pub fn is_infinite(&self) -> bool {
454 (self.bits & decnumber_sys::DECINF) != 0
455 }
456
457 pub fn is_nan(&self) -> bool {
459 (self.bits & (decnumber_sys::DECNAN | decnumber_sys::DECSNAN)) != 0
460 }
461
462 pub fn is_negative(&self) -> bool {
468 (self.bits & decnumber_sys::DECNEG) != 0
469 }
470
471 pub fn is_quiet_nan(&self) -> bool {
473 (self.bits & decnumber_sys::DECNAN) != 0
474 }
475
476 pub fn is_signaling_nan(&self) -> bool {
478 (self.bits & decnumber_sys::DECSNAN) != 0
479 }
480
481 pub fn is_special(&self) -> bool {
486 (self.bits & decnumber_sys::DECSPECIAL) != 0
487 }
488
489 pub fn is_zero(&self) -> bool {
491 self.is_finite() && self.lsu[0] == 0 && self.digits == 1
492 }
493
494 pub fn quantum_matches(&self, rhs: &Decimal<N>) -> bool {
500 let mut d = Decimal::<N>::zero();
501 unsafe {
502 decnumber_sys::decNumberSameQuantum(
503 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
504 self.as_ptr(),
505 rhs.as_ptr(),
506 );
507 };
508 if d.is_zero() {
509 false
510 } else {
511 debug_assert!(!d.is_special());
512 true
513 }
514 }
515
516 pub fn to_decimal32(&self) -> Decimal32 {
521 Context::<Decimal32>::default().from_decimal(self)
522 }
523
524 pub fn to_decimal64(&self) -> Decimal64 {
529 Context::<Decimal64>::default().from_decimal(self)
530 }
531
532 pub fn to_decimal128(&self) -> Decimal128 {
537 Context::<Decimal128>::default().from_decimal(self)
538 }
539
540 pub fn to_raw_parts(&self) -> (u32, i32, u8, [u16; N]) {
547 (self.digits, self.exponent, self.bits, self.lsu)
548 }
549
550 pub fn from_raw_parts(digits: u32, exponent: i32, bits: u8, lsu: [u16; N]) -> Self {
553 Decimal {
554 digits,
555 exponent,
556 bits,
557 lsu,
558 }
559 }
560
561 pub fn to_packed_bcd(&mut self) -> Option<(Vec<u8>, i32)> {
566 if self.is_special() {
567 return None;
568 }
569 let mut len = (usize::try_from(self.digits).unwrap() + 1) / 2;
570 if self.digits % 2 == 0 {
571 len += 1;
573 }
574
575 let mut bcd = vec![0; len];
576 let mut scale: i32 = 0;
577 let ret = unsafe {
578 decnumber_sys::decPackedFromNumber(
579 bcd.as_mut_ptr() as *mut u8,
580 len.try_into().unwrap(),
581 &mut scale as *mut i32,
582 self.as_mut_ptr() as *mut decnumber_sys::decNumber,
583 )
584 };
585 assert!(!ret.is_null());
588 Some((bcd, scale))
589 }
590
591 pub fn from_packed_bcd(bcd: &[u8], scale: i32) -> Result<Decimal<N>, FromBcdError> {
603 let mut d = Decimal::default();
604 let ret = unsafe {
605 decnumber_sys::decPackedToNumber(
606 bcd.as_ptr() as *const u8,
607 bcd.len().try_into().unwrap(),
608 &scale as *const i32,
609 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
610 )
611 };
612
613 if ret.is_null() {
614 Err(FromBcdError)
615 } else {
616 Ok(d)
617 }
618 }
619
620 pub fn to_standard_notation_string(&self) -> String {
623 if !self.is_finite() {
624 return self.to_string();
625 }
626 let digits = self.coefficient_digits();
627 let digits = {
628 let i = digits
629 .iter()
630 .position(|d| *d != 0)
631 .unwrap_or(digits.len() - 1);
632 &digits[i..]
633 };
634 let ndigits = digits.len() as i32;
635 let e = self.exponent();
636 let mut out = String::with_capacity(digits.len() + 3);
640 if self.is_negative() {
641 out.push('-');
642 }
643
644 if e >= 0 {
645 for d in digits {
647 out.push(char::from(b'0' + *d));
648 }
649 if !self.is_zero() {
650 for _ in 0..e {
651 out.push('0');
652 }
653 }
654 } else if ndigits > -e {
655 let e = (ndigits + e) as usize;
657 for d in &digits[..e] {
658 out.push(char::from(b'0' + *d));
659 }
660 out.push('.');
661 for d in &digits[e..] {
662 out.push(char::from(b'0' + *d));
663 }
664 } else {
665 out.push_str("0.");
667 for _ in 0..(-e - ndigits) {
668 out.push('0');
669 }
670 for d in digits {
671 out.push(char::from(b'0' + *d));
672 }
673 }
674 out
675 }
676
677 pub fn trim(&mut self) {
680 unsafe {
681 decnumber_sys::decNumberTrim(self.as_mut_ptr());
682 }
683 }
684}
685
686impl<const N: usize> Default for Decimal<N> {
687 fn default() -> Decimal<N> {
688 validate_n(N);
689 Decimal::<N> {
690 digits: 1,
691 bits: 0,
692 exponent: 0,
693 lsu: [0; N],
694 }
695 }
696}
697
698impl<const N: usize> PartialOrd for Decimal<N> {
699 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
700 Context::<Decimal<N>>::default().partial_cmp(self, other)
701 }
702}
703
704impl<const N: usize> PartialEq for Decimal<N> {
705 fn eq(&self, other: &Self) -> bool {
706 self.partial_cmp(other) == Some(Ordering::Equal)
707 }
708}
709
710impl<const N: usize> Neg for Decimal<N> {
711 type Output = Decimal<N>;
712
713 fn neg(self) -> Decimal<N> {
716 let mut n = self.clone();
717 let n_ptr = n.as_mut_ptr();
718 unsafe {
719 decnumber_sys::decNumberCopyNegate(n_ptr, n_ptr);
720 }
721 n
722 }
723}
724
725impl<const M: usize, const N: usize> Add<Decimal<M>> for Decimal<N> {
726 type Output = Self;
727
728 fn add(self, rhs: Decimal<M>) -> Self {
731 let mut lhs = self.clone();
732 Context::<Self>::default().add(&mut lhs, &rhs);
733 lhs
734 }
735}
736
737impl<const M: usize, const N: usize> AddAssign<Decimal<M>> for Decimal<N> {
738 fn add_assign(&mut self, rhs: Decimal<M>) {
739 Context::<Self>::default().add(self, &rhs);
740 }
741}
742
743impl<const M: usize, const N: usize> Div<Decimal<M>> for Decimal<N> {
744 type Output = Self;
745
746 fn div(self, rhs: Decimal<M>) -> Self {
749 let mut lhs = self.clone();
750 Context::<Self>::default().div(&mut lhs, &rhs);
751 lhs
752 }
753}
754
755impl<const M: usize, const N: usize> DivAssign<Decimal<M>> for Decimal<N> {
756 fn div_assign(&mut self, rhs: Decimal<M>) {
757 Context::<Self>::default().div(self, &rhs);
758 }
759}
760
761impl<const M: usize, const N: usize> Mul<Decimal<M>> for Decimal<N> {
762 type Output = Self;
763
764 fn mul(self, rhs: Decimal<M>) -> Self {
767 let mut lhs = self.clone();
768 Context::<Self>::default().mul(&mut lhs, &rhs);
769 lhs
770 }
771}
772
773impl<const M: usize, const N: usize> MulAssign<Decimal<M>> for Decimal<N> {
774 fn mul_assign(&mut self, rhs: Decimal<M>) {
775 Context::<Self>::default().mul(self, &rhs);
776 }
777}
778
779impl<const M: usize, const N: usize> Rem<Decimal<M>> for Decimal<N> {
780 type Output = Self;
781
782 fn rem(self, rhs: Decimal<M>) -> Self {
785 let mut lhs = self.clone();
786 Context::<Self>::default().rem(&mut lhs, &rhs);
787 lhs
788 }
789}
790
791impl<const M: usize, const N: usize> RemAssign<Decimal<M>> for Decimal<N> {
792 fn rem_assign(&mut self, rhs: Decimal<M>) {
793 Context::<Self>::default().rem(self, &rhs);
794 }
795}
796
797impl<const M: usize, const N: usize> Sub<Decimal<M>> for Decimal<N> {
798 type Output = Self;
799
800 fn sub(self, rhs: Decimal<M>) -> Self {
803 let mut lhs = self.clone();
804 Context::<Self>::default().sub(&mut lhs, &rhs);
805 lhs
806 }
807}
808
809impl<const M: usize, const N: usize> SubAssign<Decimal<M>> for Decimal<N> {
810 fn sub_assign(&mut self, rhs: Decimal<M>) {
811 Context::<Self>::default().sub(self, &rhs);
812 }
813}
814
815impl<const M: usize, const N: usize> Sum<Decimal<M>> for Decimal<N> {
816 fn sum<I>(iter: I) -> Self
817 where
818 I: Iterator<Item = Decimal<M>>,
819 {
820 iter.map(|v| v).collect::<Vec<_>>().iter().sum()
821 }
822}
823
824impl<'a, const M: usize, const N: usize> Sum<&'a Decimal<M>> for Decimal<N> {
825 fn sum<I>(iter: I) -> Self
826 where
827 I: Iterator<Item = &'a Decimal<M>>,
828 {
829 let mut cx = Context::<Self>::default();
830 cx.sum(iter)
831 }
832}
833
834impl<const M: usize, const N: usize> Product<Decimal<M>> for Decimal<N> {
835 fn product<I>(iter: I) -> Self
836 where
837 I: Iterator<Item = Decimal<M>>,
838 {
839 iter.map(|v| v).collect::<Vec<_>>().iter().product()
840 }
841}
842
843impl<'a, const M: usize, const N: usize> Product<&'a Decimal<M>> for Decimal<N> {
844 fn product<I>(iter: I) -> Self
845 where
846 I: Iterator<Item = &'a Decimal<M>>,
847 {
848 let mut cx = Context::<Self>::default();
849 cx.product(iter)
850 }
851}
852
853impl<const N: usize> fmt::Debug for Decimal<N> {
854 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
855 fmt::Display::fmt(self, f)
856 }
857}
858
859impl<const N: usize> fmt::Display for Decimal<N> {
860 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
861 let mut buf = Vec::with_capacity(self.digits as usize + 14);
864 let c_str = unsafe {
865 if f.alternate() {
866 decnumber_sys::decNumberToEngString(self.as_ptr(), buf.as_mut_ptr() as *mut c_char);
867 } else {
868 decnumber_sys::decNumberToString(self.as_ptr(), buf.as_mut_ptr() as *mut c_char);
869 }
870 CStr::from_ptr(buf.as_ptr() as *const c_char)
871 };
872 f.write_str(
873 c_str
874 .to_str()
875 .expect("decNumberToString yields valid UTF-8"),
876 )
877 }
878}
879
880impl<const N: usize> FromStr for Decimal<N> {
881 type Err = ParseDecimalError;
882
883 fn from_str(s: &str) -> Result<Decimal<N>, ParseDecimalError> {
884 Context::<Decimal<N>>::default().parse(s)
885 }
886}
887
888macro_rules! __decnum_tryinto_primitive {
891 ($p:ty, $cx:expr, $max_digits:literal, $d:expr, $allow_neg:expr) => {{
892 $cx.rescale(&mut $d, &Decimal::<N>::zero());
893
894 let inexact = $cx.status().inexact();
896
897 let mut fail = || -> TryFromDecimalError {
898 let mut s = $cx.status();
899 s.set_invalid_operation();
900 $cx.set_status(s);
901 TryFromDecimalError
902 };
903
904 if $d.is_special()
905 || $d.digits() > $max_digits
906 || (!$allow_neg && $d.is_negative())
907 || inexact
908 {
909 return Err(fail());
910 }
911
912 let accum_op = if $d.is_negative() {
913 <$p>::checked_sub
914 } else {
915 <$p>::checked_add
916 };
917 let ten: $p = 10;
918 let mut ten_pow = 0;
919
920 let mut accum = 0;
921 || -> Option<$p> {
923 for v in $d.coefficient_units() {
924 let d = <$p>::from(*v).checked_mul(ten.pow(ten_pow))?;
925 accum = accum_op(accum, d)?;
926 ten_pow += decnumber_sys::DECDPUN as u32;
927 }
928 Some(accum)
929 }()
930 .ok_or_else(|| fail())
931 }};
932}
933
934macro_rules! decnum_tryinto_primitive_int {
935 ($p:ty, $cx:expr, $max_digits:literal, $d:expr) => {{
936 __decnum_tryinto_primitive!($p, $cx, $max_digits, $d, true)
937 }};
938}
939
940macro_rules! decnum_tryinto_primitive_uint {
941 ($p:ty, $cx:expr, $max_digits:literal, $d:expr) => {{
942 __decnum_tryinto_primitive!($p, $cx, $max_digits, $d, false)
943 }};
944}
945
946impl<const N: usize> TryFrom<Decimal<N>> for i8 {
949 type Error = TryFromDecimalError;
950 fn try_from(n: Decimal<N>) -> Result<i8, Self::Error> {
951 let mut cx = Context::<Decimal<N>>::default();
952 cx.try_into_i8(n)
953 }
954}
955
956impl<const N: usize> TryFrom<Decimal<N>> for u8 {
959 type Error = TryFromDecimalError;
960 fn try_from(n: Decimal<N>) -> Result<u8, Self::Error> {
961 let mut cx = Context::<Decimal<N>>::default();
962 cx.try_into_u8(n)
963 }
964}
965
966impl<const N: usize> TryFrom<Decimal<N>> for i16 {
969 type Error = TryFromDecimalError;
970 fn try_from(n: Decimal<N>) -> Result<i16, Self::Error> {
971 let mut cx = Context::<Decimal<N>>::default();
972 cx.try_into_i16(n)
973 }
974}
975
976impl<const N: usize> TryFrom<Decimal<N>> for u16 {
979 type Error = TryFromDecimalError;
980 fn try_from(n: Decimal<N>) -> Result<u16, Self::Error> {
981 let mut cx = Context::<Decimal<N>>::default();
982 cx.try_into_u16(n)
983 }
984}
985
986impl<const N: usize> TryFrom<Decimal<N>> for i32 {
989 type Error = TryFromDecimalError;
990 fn try_from(n: Decimal<N>) -> Result<i32, Self::Error> {
991 let mut cx = Context::<Decimal<N>>::default();
992 cx.try_into_i32(n)
993 }
994}
995
996impl<const N: usize> TryFrom<Decimal<N>> for u32 {
999 type Error = TryFromDecimalError;
1000 fn try_from(n: Decimal<N>) -> Result<u32, Self::Error> {
1001 let mut cx = Context::<Decimal<N>>::default();
1002 cx.try_into_u32(n)
1003 }
1004}
1005
1006impl<const N: usize> TryFrom<Decimal<N>> for i64 {
1009 type Error = TryFromDecimalError;
1010 fn try_from(n: Decimal<N>) -> Result<i64, Self::Error> {
1011 let mut cx = Context::<Decimal<N>>::default();
1012 cx.try_into_i64(n)
1013 }
1014}
1015
1016impl<const N: usize> TryFrom<Decimal<N>> for u64 {
1019 type Error = TryFromDecimalError;
1020 fn try_from(n: Decimal<N>) -> Result<u64, Self::Error> {
1021 let mut cx = Context::<Decimal<N>>::default();
1022 cx.try_into_u64(n)
1023 }
1024}
1025
1026impl<const N: usize> TryFrom<Decimal<N>> for i128 {
1029 type Error = TryFromDecimalError;
1030 fn try_from(n: Decimal<N>) -> Result<i128, Self::Error> {
1031 let mut cx = Context::<Decimal<N>>::default();
1032 cx.try_into_i128(n)
1033 }
1034}
1035
1036impl<const N: usize> TryFrom<Decimal<N>> for u128 {
1039 type Error = TryFromDecimalError;
1040 fn try_from(n: Decimal<N>) -> Result<u128, Self::Error> {
1041 let mut cx = Context::<Decimal<N>>::default();
1042 cx.try_into_u128(n)
1043 }
1044}
1045
1046impl<const N: usize> TryFrom<Decimal<N>> for usize {
1049 type Error = TryFromDecimalError;
1050 fn try_from(n: Decimal<N>) -> Result<usize, Self::Error> {
1051 let mut cx = Context::<Decimal<N>>::default();
1052 cx.try_into_usize(n)
1053 }
1054}
1055
1056impl<const N: usize> TryFrom<Decimal<N>> for isize {
1059 type Error = TryFromDecimalError;
1060 fn try_from(n: Decimal<N>) -> Result<isize, Self::Error> {
1061 let mut cx = Context::<Decimal<N>>::default();
1062 cx.try_into_isize(n)
1063 }
1064}
1065
1066macro_rules! decnum_tryinto_primitive_float {
1067 ($p:ty, $cx:expr, $d:expr) => {{
1068 if $d.is_infinite() {
1069 return Ok(if $d.is_negative() {
1070 <$p>::NEG_INFINITY
1071 } else {
1072 <$p>::INFINITY
1073 });
1074 }
1075 if $d.is_nan() {
1076 return Ok(<$p>::NAN);
1077 }
1078
1079 const TEN: $p = 10.0;
1080 const DECDPUN_F: $p = decnumber_sys::DECDPUN as $p;
1081
1082 let mut e = $d.exponent() as $p;
1083 let mut f: $p = 0.0;
1084 for u in $d.coefficient_units() {
1085 f += <$p>::from(*u) * TEN.powf(e);
1087 e += DECDPUN_F;
1088 }
1089 if $d.is_negative() {
1090 f = -f;
1091 }
1092
1093 if f.is_infinite() || f.is_nan() || (!$d.is_zero() && f == 0.0) {
1099 let mut s = $cx.status();
1100 s.set_invalid_operation();
1101 $cx.set_status(s);
1102 Err(TryFromDecimalError)
1103 } else {
1104 Ok(f)
1105 }
1106 }};
1107}
1108
1109impl<const N: usize> TryFrom<Decimal<N>> for f32 {
1110 type Error = TryFromDecimalError;
1111 fn try_from(n: Decimal<N>) -> Result<f32, Self::Error> {
1112 let mut cx = Context::<Decimal<N>>::default();
1113 cx.try_into_f32(n)
1114 }
1115}
1116
1117impl<const N: usize> TryFrom<Decimal<N>> for f64 {
1118 type Error = TryFromDecimalError;
1119 fn try_from(n: Decimal<N>) -> Result<f64, Self::Error> {
1120 let mut cx = Context::<Decimal<N>>::default();
1121 cx.try_into_f64(n)
1122 }
1123}
1124
1125impl<const N: usize> From<f32> for Decimal<N> {
1126 fn from(n: f32) -> Decimal<N> {
1127 let mut cx = Context::<Decimal<N>>::default();
1128 cx.from_f32(n)
1129 }
1130}
1131
1132impl<const N: usize> From<f64> for Decimal<N> {
1133 fn from(n: f64) -> Decimal<N> {
1134 let mut cx = Context::<Decimal<N>>::default();
1135 cx.from_f64(n)
1136 }
1137}
1138
1139impl<const N: usize> From<i8> for Decimal<N> {
1140 fn from(n: i8) -> Decimal<N> {
1141 Decimal::<N>::from(i32::from(n))
1142 }
1143}
1144
1145impl<const N: usize> From<u8> for Decimal<N> {
1146 fn from(n: u8) -> Decimal<N> {
1147 Decimal::<N>::from(u32::from(n))
1148 }
1149}
1150
1151impl<const N: usize> From<i16> for Decimal<N> {
1152 fn from(n: i16) -> Decimal<N> {
1153 Decimal::<N>::from(i32::from(n))
1154 }
1155}
1156
1157impl<const N: usize> From<u16> for Decimal<N> {
1158 fn from(n: u16) -> Decimal<N> {
1159 Decimal::<N>::from(u32::from(n))
1160 }
1161}
1162
1163impl<const N: usize> From<i32> for Decimal<N> {
1164 fn from(n: i32) -> Decimal<N> {
1165 let mut d = Decimal::default();
1166 unsafe {
1167 decnumber_sys::decNumberFromInt32(d.as_mut_ptr() as *mut decnumber_sys::decNumber, n);
1168 }
1169 d
1170 }
1171}
1172
1173impl<const N: usize> From<u32> for Decimal<N> {
1174 fn from(n: u32) -> Decimal<N> {
1175 let mut d = Decimal::default();
1176 unsafe {
1177 decnumber_sys::decNumberFromUInt32(d.as_mut_ptr() as *mut decnumber_sys::decNumber, n);
1178 }
1179 d
1180 }
1181}
1182
1183impl<const N: usize> From<i64> for Decimal<N> {
1184 fn from(n: i64) -> Decimal<N> {
1185 let mut cx = Context::<Decimal<N>>::default();
1186 cx.from_i64(n)
1187 }
1188}
1189
1190impl<const N: usize> From<u64> for Decimal<N> {
1191 fn from(n: u64) -> Decimal<N> {
1192 let mut cx = Context::<Decimal<N>>::default();
1193 cx.from_u64(n)
1194 }
1195}
1196
1197impl<const N: usize> TryFrom<i128> for Decimal<N> {
1203 type Error = TryIntoDecimalError;
1204 fn try_from(n: i128) -> Result<Decimal<N>, Self::Error> {
1205 let mut cx = Context::<Decimal<N>>::default();
1206 let d = cx.from_i128(n);
1207 return if cx.status().any() {
1208 Err(TryIntoDecimalError)
1209 } else {
1210 Ok(d)
1211 };
1212 }
1213}
1214
1215impl<const N: usize> TryFrom<u128> for Decimal<N> {
1221 type Error = TryIntoDecimalError;
1222 fn try_from(n: u128) -> Result<Decimal<N>, Self::Error> {
1223 let mut cx = Context::<Decimal<N>>::default();
1224 let d = cx.from_u128(n);
1225 return if cx.status().any() {
1226 Err(TryIntoDecimalError)
1227 } else {
1228 Ok(d)
1229 };
1230 }
1231}
1232
1233#[cfg(target_pointer_width = "32")]
1234impl<const N: usize> From<usize> for Decimal<N> {
1235 fn from(n: usize) -> Decimal<N> {
1236 Decimal::<N>::from(n as u32)
1237 }
1238}
1239
1240#[cfg(target_pointer_width = "32")]
1241impl<const N: usize> From<isize> for Decimal<N> {
1242 fn from(n: isize) -> Decimal<N> {
1243 Decimal::<N>::from(n as i32)
1244 }
1245}
1246
1247#[cfg(target_pointer_width = "64")]
1248impl<const N: usize> From<usize> for Decimal<N> {
1249 fn from(n: usize) -> Decimal<N> {
1250 Decimal::<N>::from(n as u64)
1251 }
1252}
1253
1254#[cfg(target_pointer_width = "64")]
1255impl<const N: usize> From<isize> for Decimal<N> {
1256 fn from(n: isize) -> Decimal<N> {
1257 Decimal::<N>::from(n as i64)
1258 }
1259}
1260
1261impl<const N: usize> From<Decimal32> for Decimal<N> {
1262 fn from(n: Decimal32) -> Decimal<N> {
1263 let mut d = Decimal::default();
1264 unsafe {
1265 decnumber_sys::decimal32ToNumber(
1266 &n.inner,
1267 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1268 );
1269 }
1270 d
1271 }
1272}
1273
1274impl<const N: usize> From<Decimal64> for Decimal<N> {
1275 fn from(n: Decimal64) -> Decimal<N> {
1276 let mut d = Decimal::default();
1277 unsafe {
1278 decnumber_sys::decimal64ToNumber(
1279 &n.inner,
1280 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1281 );
1282 }
1283 d
1284 }
1285}
1286
1287impl<const N: usize> From<Decimal128> for Decimal<N> {
1288 fn from(n: Decimal128) -> Decimal<N> {
1289 let mut d = Decimal::default();
1290 unsafe {
1291 decnumber_sys::decimal128ToNumber(
1292 &n.inner,
1293 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1294 );
1295 }
1296 d
1297 }
1298}
1299
1300impl<const N: usize> Default for Context<Decimal<N>> {
1301 fn default() -> Context<Decimal<N>> {
1302 let mut ctx = MaybeUninit::<decnumber_sys::decContext>::uninit();
1303 let mut ctx = unsafe {
1304 decnumber_sys::decContextDefault(ctx.as_mut_ptr(), decnumber_sys::DEC_INIT_BASE);
1305 ctx.assume_init()
1306 };
1307 ctx.traps = 0;
1308 ctx.digits = i32::try_from(N * decnumber_sys::DECDPUN)
1311 .expect("decimal digit count does not fit into i32");
1312 Context {
1313 inner: ctx,
1314 _phantom: PhantomData,
1315 }
1316 }
1317}
1318
1319impl<const N: usize> Context<Decimal<N>> {
1320 pub fn precision(&self) -> usize {
1325 usize::try_from(self.inner.digits).expect("context digit count does not fit into usize")
1326 }
1327
1328 pub fn set_precision(&mut self, precision: usize) -> Result<(), InvalidPrecisionError> {
1332 if precision < 1 || precision > N * decnumber_sys::DECDPUN {
1333 return Err(InvalidPrecisionError);
1334 }
1335 self.inner.digits = i32::try_from(precision).map_err(|_| InvalidPrecisionError)?;
1336 Ok(())
1337 }
1338
1339 pub fn clamp(&self) -> bool {
1346 self.inner.clamp != 0
1347 }
1348
1349 pub fn set_clamp(&mut self, clamp: bool) {
1351 self.inner.clamp = u8::from(clamp)
1352 }
1353
1354 pub fn max_exponent(&self) -> isize {
1361 isize::try_from(self.inner.emax).expect("context max exponent does not fit into isize")
1362 }
1363
1364 pub fn set_max_exponent(&mut self, e: isize) -> Result<(), InvalidExponentError> {
1369 if e < 0 || e > 999999999 {
1370 return Err(InvalidExponentError);
1371 }
1372 self.inner.emax = i32::try_from(e).map_err(|_| InvalidExponentError)?;
1373 Ok(())
1374 }
1375
1376 pub fn min_exponent(&self) -> isize {
1383 isize::try_from(self.inner.emin).expect("context min exponent does not fit into isize")
1384 }
1385
1386 pub fn set_min_exponent(&mut self, e: isize) -> Result<(), InvalidExponentError> {
1391 if e > 0 || e < -999999999 {
1392 return Err(InvalidExponentError);
1393 }
1394 self.inner.emin = i32::try_from(e).map_err(|_| InvalidExponentError)?;
1395 Ok(())
1396 }
1397
1398 pub fn parse<S>(&mut self, s: S) -> Result<Decimal<N>, ParseDecimalError>
1400 where
1401 S: Into<Vec<u8>>,
1402 {
1403 validate_n(N);
1404 let c_string = CString::new(s).map_err(|_| ParseDecimalError)?;
1405 let mut d = Decimal::zero();
1406 unsafe {
1407 decnumber_sys::decNumberFromString(
1408 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1409 c_string.as_ptr(),
1410 &mut self.inner,
1411 );
1412 };
1413 if (self.inner.status & decnumber_sys::DEC_Conversion_syntax) != 0 {
1414 Err(ParseDecimalError)
1415 } else {
1416 Ok(d)
1417 }
1418 }
1419
1420 pub fn class(&mut self, n: &Decimal<N>) -> Class {
1422 Class::from_c(unsafe { decnumber_sys::decNumberClass(n.as_ptr(), &mut self.inner) })
1423 }
1424
1425 pub fn abs(&mut self, n: &mut Decimal<N>) {
1431 let n = n.as_mut_ptr();
1432 unsafe {
1433 decnumber_sys::decNumberAbs(n, n, &mut self.inner);
1434 }
1435 }
1436
1437 pub fn add<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1439 let lhs = lhs.as_mut_ptr();
1440 unsafe {
1441 decnumber_sys::decNumberAdd(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1442 }
1443 }
1444
1445 pub fn and<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1448 let lhs = lhs.as_mut_ptr();
1449 unsafe {
1450 decnumber_sys::decNumberAnd(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1451 }
1452 }
1453
1454 pub fn div<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1456 let lhs = lhs.as_mut_ptr();
1457 unsafe {
1458 decnumber_sys::decNumberDivide(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1459 }
1460 }
1461
1462 pub fn div_integer<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1464 let lhs = lhs.as_mut_ptr();
1465 unsafe {
1466 decnumber_sys::decNumberDivideInteger(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1467 }
1468 }
1469
1470 pub fn exp(&mut self, n: &mut Decimal<N>) {
1472 let n = n.as_mut_ptr();
1473 unsafe {
1474 decnumber_sys::decNumberExp(n, n, &mut self.inner);
1475 }
1476 }
1477
1478 pub fn fma<const L: usize, const M: usize>(
1484 &mut self,
1485 x: &mut Decimal<N>,
1486 y: &Decimal<L>,
1487 z: &Decimal<M>,
1488 ) {
1489 let x = x.as_mut_ptr();
1490 unsafe {
1491 decnumber_sys::decNumberFMA(x, x, y.as_ptr(), z.as_ptr(), &mut self.inner);
1492 }
1493 }
1494
1495 pub fn from_i32(&mut self, n: i32) -> Decimal<N> {
1497 Decimal::<N>::from(n)
1498 }
1499
1500 pub fn from_u32(&mut self, n: u32) -> Decimal<N> {
1502 Decimal::<N>::from(n)
1503 }
1504
1505 pub fn from_i64(&mut self, n: i64) -> Decimal<N> {
1507 decimal_from_signed_int!(self, n)
1508 }
1509
1510 pub fn from_u64(&mut self, n: u64) -> Decimal<N> {
1512 decimal_from_unsigned_int!(self, n)
1513 }
1514
1515 pub fn from_i128(&mut self, n: i128) -> Decimal<N> {
1543 decimal_from_signed_int!(self, n)
1544 }
1545
1546 pub fn from_u128(&mut self, n: u128) -> Decimal<N> {
1569 decimal_from_unsigned_int!(self, n)
1570 }
1571
1572 pub fn try_into_u8(&mut self, d: Decimal<N>) -> Result<u8, TryFromDecimalError> {
1577 let i = self.try_into_u32(d)?;
1578 u8::try_from(i).map_err(|_| TryFromDecimalError)
1579 }
1580
1581 pub fn try_into_i8(&mut self, d: Decimal<N>) -> Result<i8, TryFromDecimalError> {
1586 let i = self.try_into_i32(d)?;
1587 i8::try_from(i).map_err(|_| TryFromDecimalError)
1588 }
1589
1590 pub fn try_into_u16(&mut self, d: Decimal<N>) -> Result<u16, TryFromDecimalError> {
1595 let i = self.try_into_u32(d)?;
1596 u16::try_from(i).map_err(|_| TryFromDecimalError)
1597 }
1598
1599 pub fn try_into_i16(&mut self, d: Decimal<N>) -> Result<i16, TryFromDecimalError> {
1604 let i = self.try_into_i32(d)?;
1605 i16::try_from(i).map_err(|_| TryFromDecimalError)
1606 }
1607
1608 pub fn try_into_i32(&mut self, mut d: Decimal<N>) -> Result<i32, TryFromDecimalError> {
1623 self.rescale(&mut d, &Decimal::<N>::zero());
1624 let i = unsafe { decnumber_sys::decNumberToInt32(d.as_ptr(), &mut self.inner) };
1625 if self.status().invalid_operation() || self.status().inexact() {
1627 Err(TryFromDecimalError)
1628 } else {
1629 Ok(i)
1630 }
1631 }
1632
1633 pub fn try_into_u32(&mut self, mut d: Decimal<N>) -> Result<u32, TryFromDecimalError> {
1638 self.rescale(&mut d, &Decimal::<N>::zero());
1639 let i = unsafe { decnumber_sys::decNumberToUInt32(d.as_ptr(), &mut self.inner) };
1640 if self.status().invalid_operation() || self.status().inexact() {
1642 Err(TryFromDecimalError)
1643 } else {
1644 Ok(i)
1645 }
1646 }
1647
1648 #[cfg(target_pointer_width = "32")]
1653 pub fn try_into_isize(&mut self, d: Decimal<N>) -> Result<isize, TryFromDecimalError> {
1654 let d = self.try_into_i32(d)?;
1655 Ok(d as isize)
1656 }
1657
1658 #[cfg(target_pointer_width = "64")]
1663 pub fn try_into_isize(&mut self, d: Decimal<N>) -> Result<isize, TryFromDecimalError> {
1664 let d = self.try_into_i64(d)?;
1665 Ok(d as isize)
1666 }
1667
1668 pub fn try_into_i64(&mut self, mut d: Decimal<N>) -> Result<i64, TryFromDecimalError> {
1673 decnum_tryinto_primitive_int!(i64, self, 19, d)
1674 }
1675
1676 pub fn try_into_i128(&mut self, mut d: Decimal<N>) -> Result<i128, TryFromDecimalError> {
1681 decnum_tryinto_primitive_int!(i128, self, 39, d)
1682 }
1683
1684 #[cfg(target_pointer_width = "32")]
1689 pub fn try_into_usize(&mut self, d: Decimal<N>) -> Result<usize, TryFromDecimalError> {
1690 let d = self.try_into_u32(d)?;
1691 Ok(d as usize)
1692 }
1693
1694 #[cfg(target_pointer_width = "64")]
1699 pub fn try_into_usize(&mut self, d: Decimal<N>) -> Result<usize, TryFromDecimalError> {
1700 let d = self.try_into_u64(d)?;
1701 Ok(d as usize)
1702 }
1703
1704 pub fn try_into_u64(&mut self, mut d: Decimal<N>) -> Result<u64, TryFromDecimalError> {
1709 decnum_tryinto_primitive_uint!(u64, self, 20, d)
1710 }
1711
1712 pub fn try_into_u128(&mut self, mut d: Decimal<N>) -> Result<u128, TryFromDecimalError> {
1717 decnum_tryinto_primitive_uint!(u128, self, 39, d)
1718 }
1719
1720 pub fn try_into_f32(&mut self, d: Decimal<N>) -> Result<f32, TryFromDecimalError> {
1727 decnum_tryinto_primitive_float!(f32, self, d)
1728 }
1729
1730 pub fn try_into_f64(&mut self, d: Decimal<N>) -> Result<f64, TryFromDecimalError> {
1735 decnum_tryinto_primitive_float!(f64, self, d)
1736 }
1737
1738 pub fn from_f32(&mut self, n: f32) -> Decimal<N> {
1747 self.parse(n.to_string().as_str()).unwrap()
1748 }
1749
1750 pub fn from_f64(&mut self, n: f64) -> Decimal<N> {
1759 self.parse(n.to_string().as_str()).unwrap()
1760 }
1761
1762 pub fn invert(&mut self, n: &mut Decimal<N>) {
1765 let n = n.as_mut_ptr();
1766 unsafe {
1767 decnumber_sys::decNumberInvert(n, n, &mut self.inner);
1768 }
1769 }
1770
1771 pub fn ln(&mut self, n: &mut Decimal<N>) {
1773 let n = n.as_mut_ptr();
1774 unsafe {
1775 decnumber_sys::decNumberLn(n, n, &mut self.inner);
1776 }
1777 }
1778
1779 pub fn log10(&mut self, n: &mut Decimal<N>) {
1781 let n = n.as_mut_ptr();
1782 unsafe {
1783 decnumber_sys::decNumberLog10(n, n, &mut self.inner);
1784 }
1785 }
1786
1787 pub fn logb(&mut self, n: &mut Decimal<N>) {
1790 let n = n.as_mut_ptr();
1791 unsafe {
1792 decnumber_sys::decNumberLogB(n, n, &mut self.inner);
1793 }
1794 }
1795
1796 pub fn max<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1801 let lhs = lhs.as_mut_ptr();
1802 unsafe {
1803 decnumber_sys::decNumberMax(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1804 }
1805 }
1806
1807 pub fn max_abs<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1810 let lhs = lhs.as_mut_ptr();
1811 unsafe {
1812 decnumber_sys::decNumberMaxMag(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1813 }
1814 }
1815
1816 pub fn min<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1821 let lhs = lhs.as_mut_ptr();
1822 unsafe {
1823 decnumber_sys::decNumberMin(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1824 }
1825 }
1826
1827 pub fn min_abs<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1830 let lhs = lhs.as_mut_ptr();
1831 unsafe {
1832 decnumber_sys::decNumberMinMag(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1833 }
1834 }
1835
1836 pub fn minus(&mut self, n: &mut Decimal<N>) {
1838 unsafe {
1839 decnumber_sys::decNumberMinus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1840 }
1841 }
1842
1843 pub fn mul<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1845 let lhs = lhs.as_mut_ptr();
1846 unsafe {
1847 decnumber_sys::decNumberMultiply(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1848 }
1849 }
1850
1851 pub fn neg(&mut self, n: &mut Decimal<N>) {
1854 unsafe {
1855 decnumber_sys::decNumberCopyNegate(n.as_mut_ptr(), n.as_ptr());
1856 }
1857 }
1858
1859 pub fn next_minus(&mut self, n: &mut Decimal<N>) {
1864 unsafe {
1865 decnumber_sys::decNumberNextMinus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1866 }
1867 }
1868
1869 pub fn next_plus(&mut self, n: &mut Decimal<N>) {
1874 unsafe {
1875 decnumber_sys::decNumberNextPlus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1876 }
1877 }
1878
1879 pub fn next_toward<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
1885 unsafe {
1886 decnumber_sys::decNumberNextToward(
1887 x.as_mut_ptr(),
1888 x.as_ptr(),
1889 y.as_ptr(),
1890 &mut self.inner,
1891 );
1892 }
1893 }
1894
1895 pub fn or<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1898 let lhs = lhs.as_mut_ptr();
1899 unsafe {
1900 decnumber_sys::decNumberOr(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1901 }
1902 }
1903
1904 pub fn partial_cmp<const L: usize, const M: usize>(
1910 &mut self,
1911 lhs: &Decimal<L>,
1912 rhs: &Decimal<M>,
1913 ) -> Option<Ordering> {
1914 validate_n(N);
1915 let mut d = Decimal::<N>::zero();
1916 unsafe {
1917 decnumber_sys::decNumberCompare(
1918 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1919 lhs.as_ptr(),
1920 rhs.as_ptr(),
1921 &mut self.inner,
1922 )
1923 };
1924 if d.is_nan() {
1925 None
1926 } else if d.is_negative() {
1927 Some(Ordering::Less)
1928 } else if d.is_zero() {
1929 Some(Ordering::Equal)
1930 } else {
1931 debug_assert!(!d.is_special());
1932 Some(Ordering::Greater)
1933 }
1934 }
1935
1936 pub fn plus(&mut self, n: &mut Decimal<N>) {
1938 let n = n.as_mut_ptr();
1939 unsafe {
1940 decnumber_sys::decNumberPlus(n, n, &mut self.inner);
1941 }
1942 }
1943
1944 pub fn pow<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
1946 let x = x.as_mut_ptr();
1947 unsafe {
1948 decnumber_sys::decNumberPower(x, x, y.as_ptr(), &mut self.inner);
1949 }
1950 }
1951
1952 pub fn product<'a, I, const M: usize>(&mut self, iter: I) -> Decimal<N>
1954 where
1955 I: Iterator<Item = &'a Decimal<M>>,
1956 {
1957 iter.fold(Decimal::<N>::from(1), |mut product, d| {
1958 self.mul(&mut product, &d);
1959 product
1960 })
1961 }
1962
1963 pub fn quantize<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1966 let lhs = lhs.as_mut_ptr();
1967 unsafe {
1968 decnumber_sys::decNumberQuantize(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1969 }
1970 }
1971
1972 pub fn reduce(&mut self, n: &mut Decimal<N>) {
1975 let n = n.as_mut_ptr();
1976 unsafe {
1977 decnumber_sys::decNumberReduce(n, n, &mut self.inner);
1978 }
1979 }
1980
1981 pub fn rem<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1983 let lhs = lhs.as_mut_ptr();
1984 unsafe {
1985 decnumber_sys::decNumberRemainder(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1986 }
1987 }
1988
1989 pub fn rem_near<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1992 let lhs = lhs.as_mut_ptr();
1993 unsafe {
1994 decnumber_sys::decNumberRemainderNear(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1995 }
1996 }
1997
1998 pub fn rescale<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2000 let lhs = lhs.as_mut_ptr();
2001 unsafe {
2002 decnumber_sys::decNumberRescale(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2003 }
2004 }
2005
2006 pub fn round(&mut self, n: &mut Decimal<N>) {
2009 let n = n.as_mut_ptr();
2010 unsafe {
2011 decnumber_sys::decNumberToIntegralExact(n, n, &mut self.inner);
2012 }
2013 }
2014
2015 pub fn round_to_place(
2024 &mut self,
2025 n: &mut Decimal<N>,
2026 place: usize,
2027 ) -> Result<(), InvalidPrecisionError> {
2028 let precision = self.precision();
2029 self.set_precision(place)?;
2030 self.plus(n);
2031 self.set_precision(precision)
2032 }
2033
2034 pub fn round_reduce_to_place(
2037 &mut self,
2038 n: &mut Decimal<N>,
2039 place: usize,
2040 ) -> Result<(), InvalidPrecisionError> {
2041 let precision = self.precision();
2042 self.set_precision(place)?;
2043 self.reduce(n);
2044 self.set_precision(precision)
2045 }
2046
2047 pub fn shift<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2055 let lhs = lhs.as_mut_ptr();
2056 unsafe {
2057 decnumber_sys::decNumberShift(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2058 }
2059 }
2060
2061 pub fn rotate<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2069 let lhs = lhs.as_mut_ptr();
2070 unsafe {
2071 decnumber_sys::decNumberRotate(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2072 }
2073 }
2074
2075 pub fn scaleb<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
2077 unsafe {
2078 decnumber_sys::decNumberScaleB(x.as_mut_ptr(), x.as_ptr(), y.as_ptr(), &mut self.inner);
2079 }
2080 }
2081
2082 pub fn sqrt<const M: usize>(&mut self, n: &mut Decimal<M>) {
2084 let n = n.as_mut_ptr();
2085 unsafe {
2086 decnumber_sys::decNumberSquareRoot(n, n, &mut self.inner);
2087 }
2088 }
2089
2090 pub fn sub<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2092 let lhs = lhs.as_mut_ptr();
2093 unsafe {
2094 decnumber_sys::decNumberSubtract(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2095 }
2096 }
2097
2098 pub fn sum<'a, I, const M: usize>(&mut self, iter: I) -> Decimal<N>
2100 where
2101 I: Iterator<Item = &'a Decimal<M>>,
2102 {
2103 iter.fold(Decimal::<N>::zero(), |mut sum, d| {
2104 self.add(&mut sum, d);
2105 sum
2106 })
2107 }
2108
2109 pub fn total_cmp<const L: usize, const M: usize>(
2114 &mut self,
2115 lhs: &Decimal<L>,
2116 rhs: &Decimal<M>,
2117 ) -> Ordering {
2118 validate_n(N);
2119 let mut d = Decimal::<N>::zero();
2120 unsafe {
2121 decnumber_sys::decNumberCompareTotal(
2122 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
2123 lhs.as_ptr(),
2124 rhs.as_ptr(),
2125 &mut self.inner,
2126 )
2127 };
2128 debug_assert!(!d.is_special());
2129 if d.is_negative() {
2130 Ordering::Less
2131 } else if d.is_zero() {
2132 Ordering::Equal
2133 } else {
2134 Ordering::Greater
2135 }
2136 }
2137
2138 pub fn xor<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2141 let lhs = lhs.as_mut_ptr();
2142 unsafe {
2143 decnumber_sys::decNumberXor(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2144 }
2145 }
2146
2147 pub fn to_width<const M: usize>(&mut self, m: Decimal<M>) -> Decimal<N> {
2152 let mut n = Decimal::<N>::zero();
2153 unsafe {
2154 decnumber_sys::decNumberPlus(n.as_mut_ptr(), m.as_ptr(), &mut self.inner);
2155 }
2156 n
2157 }
2158}
2159
2160#[cfg(feature = "num-traits")]
2161impl<const N: usize> Zero for Decimal<N> {
2162 #[inline]
2163 fn zero() -> Self {
2164 Decimal::<N>::zero()
2165 }
2166
2167 #[inline]
2168 fn is_zero(&self) -> bool {
2169 self.is_zero()
2170 }
2171}
2172
2173#[cfg(feature = "num-traits")]
2174impl<const N: usize, const L: usize, const M: usize> MulAdd<Decimal<L>, Decimal<M>> for Decimal<N> {
2175 type Output = Self;
2176
2177 #[inline]
2178 fn mul_add(mut self, a: Decimal<L>, b: Decimal<M>) -> Self::Output {
2179 self.mul_add_assign(a, b);
2180 self
2181 }
2182}
2183
2184#[cfg(feature = "num-traits")]
2185impl<const N: usize, const L: usize, const M: usize> MulAddAssign<Decimal<L>, Decimal<M>>
2186 for Decimal<N>
2187{
2188 fn mul_add_assign(&mut self, a: Decimal<L>, b: Decimal<M>) {
2189 Context::<Self>::default().fma(self, &a, &b);
2190 }
2191}
2192
2193#[cfg(feature = "num-traits")]
2194impl<const N: usize, const M: usize> Pow<Decimal<M>> for Decimal<N> {
2195 type Output = Self;
2196
2197 fn pow(mut self, rhs: Decimal<M>) -> Self::Output {
2198 Context::<Decimal<N>>::default().pow(&mut self, &rhs);
2199
2200 self
2201 }
2202}