1use std::cmp::Ordering;
17use std::convert::{TryFrom, TryInto};
18use std::ffi::{CStr, CString};
19use std::fmt::{self, Display, LowerExp};
20use std::io::Write;
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, Pow, Zero};
32#[cfg(feature = "serde")]
33use serde::{Deserialize, Serialize};
34
35use crate::context::{Class, Context};
36use crate::decimal128::Decimal128;
37use crate::decimal32::Decimal32;
38use crate::decimal64::Decimal64;
39use crate::error::{
40 FromBcdError, InvalidCoefficientError, InvalidExponentError, InvalidPrecisionError,
41 ParseDecimalError, TryFromDecimalError, TryIntoDecimalError,
42};
43
44fn validate_n(n: usize) {
45 if n < 12 || n > 999_999_999 {
47 panic!("Decimal<N>:: N is not in the range [12, 999999999]");
48 }
49}
50
51#[repr(C)]
67#[derive(Clone, Copy)]
68#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69pub struct Decimal<const N: usize> {
70 pub(crate) digits: u32,
71 pub(crate) exponent: i32,
72 pub(crate) bits: u8,
73 #[cfg_attr(feature = "serde", serde(with = "lsu_serde"))]
77 pub(crate) lsu: [u16; N],
78}
79
80#[cfg(feature = "serde")]
81pub mod serde_decimal_from_non_float_primitives {
107 use std::convert::TryFrom;
108 use std::fmt;
109 use std::str::FromStr;
110
111 use serde::de::{self, MapAccess, SeqAccess, Visitor};
112 use serde::{Deserialize, Deserializer, Serialize};
113
114 use crate::Decimal;
115
116 pub fn serialize<S, const N: usize>(d: &Decimal<N>, serializer: S) -> Result<S::Ok, S::Error>
118 where
119 S: serde::Serializer,
120 Decimal<N>: Serialize,
121 {
122 Decimal::<N>::serialize(d, serializer)
123 }
124
125 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<Decimal<N>, D::Error>
128 where
129 D: serde::Deserializer<'de>,
130 {
131 enum Field {
132 Digits,
133 Exponent,
134 Bits,
135 Lsu,
136 }
137
138 impl<'de> Deserialize<'de> for Field {
139 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
140 where
141 D: Deserializer<'de>,
142 {
143 struct FieldVisitor;
144
145 impl<'de> Visitor<'de> for FieldVisitor {
146 type Value = Field;
147
148 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
149 formatter.write_str("`digits`, `exponent`, `bits`, or `lsu`")
150 }
151
152 fn visit_str<E>(self, value: &str) -> Result<Field, E>
153 where
154 E: de::Error,
155 {
156 match value {
157 "digits" => Ok(Field::Digits),
158 "exponent" => Ok(Field::Exponent),
159 "bits" => Ok(Field::Bits),
160 "lsu" => Ok(Field::Lsu),
161 _ => Err(de::Error::unknown_field(value, FIELDS)),
162 }
163 }
164 }
165
166 deserializer.deserialize_identifier(FieldVisitor)
167 }
168 }
169
170 struct DecimalVisitor<const N: usize>;
171
172 macro_rules! deser_try_from {
173 ($($t:ty),*) => {
174 $(
175 paste::paste! {
176 fn [< visit_ $t >]<E>(self, value: $t) -> Result<Self::Value, E>
177 where
178 E: de::Error,
179 {
180 Decimal::try_from(value).map_err(serde::de::Error::custom)
181 }
182 }
183 )*
184 };
185 }
186
187 impl<'de, const N: usize> Visitor<'de> for DecimalVisitor<N> {
188 type Value = Decimal<N>;
189
190 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
191 formatter.write_str("struct Decimal or compatible primitive")
192 }
193
194 deser_try_from!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
195
196 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
197 where
198 E: de::Error,
199 {
200 Decimal::from_str(v).map_err(serde::de::Error::custom)
201 }
202
203 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
204 where
205 E: de::Error,
206 {
207 Decimal::from_str(&v).map_err(serde::de::Error::custom)
208 }
209
210 fn visit_seq<V>(self, mut seq: V) -> Result<Decimal<N>, V::Error>
211 where
212 V: SeqAccess<'de>,
213 {
214 let digits = seq
215 .next_element()?
216 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
217 let exponent = seq
218 .next_element()?
219 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
220 let bits = seq
221 .next_element()?
222 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
223
224 let lsu: Vec<u16> = seq
225 .next_element()?
226 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
227 let lsu = super::lsu_serde::check_deserialized_vec(lsu)?;
228
229 Ok(Decimal {
230 digits,
231 exponent,
232 bits,
233 lsu,
234 })
235 }
236
237 fn visit_map<V>(self, mut map: V) -> Result<Decimal<N>, V::Error>
238 where
239 V: MapAccess<'de>,
240 {
241 let mut digits = None;
242 let mut exponent = None;
243 let mut bits = None;
244 let mut lsu = None;
245 while let Some(key) = map.next_key()? {
246 match key {
247 Field::Digits => {
248 if digits.is_some() {
249 return Err(de::Error::duplicate_field("digits"));
250 }
251 digits = Some(map.next_value()?);
252 }
253 Field::Exponent => {
254 if exponent.is_some() {
255 return Err(de::Error::duplicate_field("exponent"));
256 }
257 exponent = Some(map.next_value()?);
258 }
259 Field::Bits => {
260 if bits.is_some() {
261 return Err(de::Error::duplicate_field("bits"));
262 }
263 bits = Some(map.next_value()?);
264 }
265 Field::Lsu => {
266 if lsu.is_some() {
267 return Err(de::Error::duplicate_field("lsu"));
268 }
269 let lsu_deserialized: Vec<u16> = map.next_value()?;
270 let lsu_deserialized =
271 super::lsu_serde::check_deserialized_vec(lsu_deserialized)?;
272
273 lsu = Some(lsu_deserialized);
274 }
275 }
276 }
277 let digits = digits.ok_or_else(|| de::Error::missing_field("digits"))?;
278 let exponent = exponent.ok_or_else(|| de::Error::missing_field("exponent"))?;
279 let bits = bits.ok_or_else(|| de::Error::missing_field("bits"))?;
280 let lsu = lsu.ok_or_else(|| de::Error::missing_field("lsu"))?;
281
282 Ok(Decimal {
283 digits,
284 exponent,
285 bits,
286 lsu,
287 })
288 }
289 }
290
291 const FIELDS: &'static [&'static str] = &["digits", "exponent", "bits", "lsu"];
292 deserializer.deserialize_any(DecimalVisitor)
293 }
294}
295
296#[cfg(feature = "serde")]
297mod lsu_serde {
298 use std::convert::TryInto;
299
300 use serde::de::{Error, Unexpected};
301 use serde::ser::SerializeSeq;
302 use serde::Deserialize;
303 pub fn serialize<S, const N: usize>(v: &[u16; N], serializer: S) -> Result<S::Ok, S::Error>
304 where
305 S: serde::Serializer,
306 {
307 let mut seq = serializer.serialize_seq(Some(N))?;
308 for e in v.iter() {
309 seq.serialize_element(e)?;
310 }
311 seq.end()
312 }
313
314 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<[u16; N], D::Error>
315 where
316 D: serde::Deserializer<'de>,
317 {
318 let lsu = Vec::<u16>::deserialize(deserializer)?;
319 check_deserialized_vec(lsu)
320 }
321
322 pub fn check_deserialized_vec<const N: usize, E>(lsu: Vec<u16>) -> Result<[u16; N], E>
324 where
325 E: Error,
326 {
327 lsu.try_into().map_err(|e: Vec<u16>| {
328 Error::invalid_value(
329 Unexpected::Other(&format!("&[u16] of length {}", e.len())),
330 &format!("&[u16] of length {}", N).as_str(),
331 )
332 })
333 }
334}
335
336impl<const N: usize> Decimal<N> {
337 pub(crate) fn as_ptr(&self) -> *const decnumber_sys::decNumber {
338 self as *const Decimal<N> as *const decnumber_sys::decNumber
339 }
340
341 pub(crate) fn as_mut_ptr(&mut self) -> *mut decnumber_sys::decNumber {
342 self as *mut Decimal<N> as *mut decnumber_sys::decNumber
343 }
344
345 pub fn zero() -> Decimal<N> {
348 Decimal::default()
349 }
350
351 pub fn infinity() -> Decimal<N> {
353 let mut d = Decimal::default();
354 d.bits = decnumber_sys::DECINF;
355 d
356 }
357
358 pub fn nan() -> Decimal<N> {
360 let mut d = Decimal::default();
361 d.bits = decnumber_sys::DECNAN;
362 d
363 }
364
365 fn two_pow_32() -> Decimal<N> {
368 let mut d = Decimal::default();
369 d.digits = 10;
370 d.lsu[0..4].copy_from_slice(&[296, 967, 294, 4]);
371 d
372 }
373
374 pub fn digits(&self) -> u32 {
379 self.digits
380 }
381
382 pub fn coefficient_digits(&self) -> Vec<u8> {
387 let mut buf = vec![0; usize::try_from(self.digits()).unwrap()];
388 unsafe {
389 decnumber_sys::decNumberGetBCD(self.as_ptr(), buf.as_mut_ptr() as *mut u8);
390 };
391 buf
392 }
393
394 pub fn coefficient_units(&self) -> &[u16] {
402 let units_len = Self::digits_to_lsu_elements_len(self.digits);
403 &self.lsu[0..units_len]
404 }
405
406 pub fn coefficient<T>(&mut self) -> Result<T, InvalidCoefficientError>
410 where
411 T: TryFrom<Decimal<N>>,
412 {
413 let cur_exp = self.exponent();
415 self.set_exponent(0);
418 let coefficient = <T>::try_from(*self);
419 self.set_exponent(cur_exp);
421 match coefficient {
422 Ok(d) => Ok(d),
423 Err(_) => Err(InvalidCoefficientError),
424 }
425 }
426
427 pub fn digits_to_lsu_elements_len(digits: u32) -> usize {
433 (usize::try_from(digits).unwrap() + decnumber_sys::DECDPUN - 1) / decnumber_sys::DECDPUN
434 }
435
436 pub fn exponent(&self) -> i32 {
438 self.exponent
439 }
440
441 pub fn set_exponent(&mut self, exponent: i32) {
443 self.exponent = exponent;
444 }
445
446 pub fn is_finite(&self) -> bool {
450 (self.bits & decnumber_sys::DECSPECIAL) == 0
451 }
452
453 pub fn is_infinite(&self) -> bool {
455 (self.bits & decnumber_sys::DECINF) != 0
456 }
457
458 pub fn is_nan(&self) -> bool {
460 (self.bits & (decnumber_sys::DECNAN | decnumber_sys::DECSNAN)) != 0
461 }
462
463 pub fn is_negative(&self) -> bool {
469 (self.bits & decnumber_sys::DECNEG) != 0
470 }
471
472 pub fn is_quiet_nan(&self) -> bool {
474 (self.bits & decnumber_sys::DECNAN) != 0
475 }
476
477 pub fn is_signaling_nan(&self) -> bool {
479 (self.bits & decnumber_sys::DECSNAN) != 0
480 }
481
482 pub fn is_special(&self) -> bool {
487 (self.bits & decnumber_sys::DECSPECIAL) != 0
488 }
489
490 pub fn is_zero(&self) -> bool {
492 self.is_finite() && self.lsu[0] == 0 && self.digits == 1
493 }
494
495 pub fn quantum_matches(&self, rhs: &Decimal<N>) -> bool {
501 let mut d = Decimal::<N>::zero();
502 unsafe {
503 decnumber_sys::decNumberSameQuantum(
504 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
505 self.as_ptr(),
506 rhs.as_ptr(),
507 );
508 };
509 if d.is_zero() {
510 false
511 } else {
512 debug_assert!(!d.is_special());
513 true
514 }
515 }
516
517 pub fn to_decimal32(&self) -> Decimal32 {
522 Context::<Decimal32>::default().from_decimal(self)
523 }
524
525 pub fn to_decimal64(&self) -> Decimal64 {
530 Context::<Decimal64>::default().from_decimal(self)
531 }
532
533 pub fn to_decimal128(&self) -> Decimal128 {
538 Context::<Decimal128>::default().from_decimal(self)
539 }
540
541 pub fn to_raw_parts(&self) -> (u32, i32, u8, [u16; N]) {
548 (self.digits, self.exponent, self.bits, self.lsu)
549 }
550
551 pub fn from_raw_parts(digits: u32, exponent: i32, bits: u8, lsu: [u16; N]) -> Self {
554 Decimal {
555 digits,
556 exponent,
557 bits,
558 lsu,
559 }
560 }
561
562 pub fn to_packed_bcd(&mut self) -> Option<(Vec<u8>, i32)> {
567 if self.is_special() {
568 return None;
569 }
570 let mut len = (usize::try_from(self.digits).unwrap() + 1) / 2;
571 if self.digits % 2 == 0 {
572 len += 1;
574 }
575
576 let mut bcd = vec![0; len];
577 let mut scale: i32 = 0;
578 let ret = unsafe {
579 decnumber_sys::decPackedFromNumber(
580 bcd.as_mut_ptr() as *mut u8,
581 len.try_into().unwrap(),
582 &mut scale as *mut i32,
583 self.as_mut_ptr() as *mut decnumber_sys::decNumber,
584 )
585 };
586 assert!(!ret.is_null());
589 Some((bcd, scale))
590 }
591
592 pub fn from_packed_bcd(bcd: &[u8], scale: i32) -> Result<Decimal<N>, FromBcdError> {
604 let mut d = Decimal::default();
605 let ret = unsafe {
606 decnumber_sys::decPackedToNumber(
607 bcd.as_ptr() as *const u8,
608 bcd.len().try_into().unwrap(),
609 &scale as *const i32,
610 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
611 )
612 };
613
614 if ret.is_null() {
615 Err(FromBcdError)
616 } else {
617 Ok(d)
618 }
619 }
620
621 pub fn to_standard_notation_string(&self) -> String {
624 if !self.is_finite() {
625 return self.to_string();
626 }
627 let digits = self.coefficient_digits();
628 let digits = {
629 let i = digits
630 .iter()
631 .position(|d| *d != 0)
632 .unwrap_or(digits.len() - 1);
633 &digits[i..]
634 };
635 let ndigits = digits.len() as i32;
636 let e = self.exponent();
637 let mut out = String::with_capacity(digits.len() + 3);
641 if self.is_negative() {
642 out.push('-');
643 }
644
645 if e >= 0 {
646 for d in digits {
648 out.push(char::from(b'0' + *d));
649 }
650 if !self.is_zero() {
651 for _ in 0..e {
652 out.push('0');
653 }
654 }
655 } else if ndigits > -e {
656 let e = (ndigits + e) as usize;
658 for d in &digits[..e] {
659 out.push(char::from(b'0' + *d));
660 }
661 out.push('.');
662 for d in &digits[e..] {
663 out.push(char::from(b'0' + *d));
664 }
665 } else {
666 out.push_str("0.");
668 for _ in 0..(-e - ndigits) {
669 out.push('0');
670 }
671 for d in digits {
672 out.push(char::from(b'0' + *d));
673 }
674 }
675 out
676 }
677
678 pub fn trim(&mut self) {
681 unsafe {
682 decnumber_sys::decNumberTrim(self.as_mut_ptr());
683 }
684 }
685}
686
687impl<const N: usize> Default for Decimal<N> {
688 fn default() -> Decimal<N> {
689 validate_n(N);
690 Decimal::<N> {
691 digits: 1,
692 bits: 0,
693 exponent: 0,
694 lsu: [0; N],
695 }
696 }
697}
698
699impl<const N: usize> PartialOrd for Decimal<N> {
700 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
701 Context::<Decimal<N>>::default().partial_cmp(self, other)
702 }
703}
704
705impl<const N: usize> PartialEq for Decimal<N> {
706 fn eq(&self, other: &Self) -> bool {
707 self.partial_cmp(other) == Some(Ordering::Equal)
708 }
709}
710
711impl<const N: usize> Neg for Decimal<N> {
712 type Output = Decimal<N>;
713
714 fn neg(self) -> Decimal<N> {
717 let mut n = self.clone();
718 let n_ptr = n.as_mut_ptr();
719 unsafe {
720 decnumber_sys::decNumberCopyNegate(n_ptr, n_ptr);
721 }
722 n
723 }
724}
725
726impl<const M: usize, const N: usize> Add<Decimal<M>> for Decimal<N> {
727 type Output = Self;
728
729 fn add(self, rhs: Decimal<M>) -> Self {
732 let mut lhs = self.clone();
733 Context::<Self>::default().add(&mut lhs, &rhs);
734 lhs
735 }
736}
737
738impl<const M: usize, const N: usize> AddAssign<Decimal<M>> for Decimal<N> {
739 fn add_assign(&mut self, rhs: Decimal<M>) {
740 Context::<Self>::default().add(self, &rhs);
741 }
742}
743
744impl<const M: usize, const N: usize> Div<Decimal<M>> for Decimal<N> {
745 type Output = Self;
746
747 fn div(self, rhs: Decimal<M>) -> Self {
750 let mut lhs = self.clone();
751 Context::<Self>::default().div(&mut lhs, &rhs);
752 lhs
753 }
754}
755
756impl<const M: usize, const N: usize> DivAssign<Decimal<M>> for Decimal<N> {
757 fn div_assign(&mut self, rhs: Decimal<M>) {
758 Context::<Self>::default().div(self, &rhs);
759 }
760}
761
762impl<const M: usize, const N: usize> Mul<Decimal<M>> for Decimal<N> {
763 type Output = Self;
764
765 fn mul(self, rhs: Decimal<M>) -> Self {
768 let mut lhs = self.clone();
769 Context::<Self>::default().mul(&mut lhs, &rhs);
770 lhs
771 }
772}
773
774impl<const M: usize, const N: usize> MulAssign<Decimal<M>> for Decimal<N> {
775 fn mul_assign(&mut self, rhs: Decimal<M>) {
776 Context::<Self>::default().mul(self, &rhs);
777 }
778}
779
780impl<const M: usize, const N: usize> Rem<Decimal<M>> for Decimal<N> {
781 type Output = Self;
782
783 fn rem(self, rhs: Decimal<M>) -> Self {
786 let mut lhs = self.clone();
787 Context::<Self>::default().rem(&mut lhs, &rhs);
788 lhs
789 }
790}
791
792impl<const M: usize, const N: usize> RemAssign<Decimal<M>> for Decimal<N> {
793 fn rem_assign(&mut self, rhs: Decimal<M>) {
794 Context::<Self>::default().rem(self, &rhs);
795 }
796}
797
798impl<const M: usize, const N: usize> Sub<Decimal<M>> for Decimal<N> {
799 type Output = Self;
800
801 fn sub(self, rhs: Decimal<M>) -> Self {
804 let mut lhs = self.clone();
805 Context::<Self>::default().sub(&mut lhs, &rhs);
806 lhs
807 }
808}
809
810impl<const M: usize, const N: usize> SubAssign<Decimal<M>> for Decimal<N> {
811 fn sub_assign(&mut self, rhs: Decimal<M>) {
812 Context::<Self>::default().sub(self, &rhs);
813 }
814}
815
816impl<const M: usize, const N: usize> Sum<Decimal<M>> for Decimal<N> {
817 fn sum<I>(iter: I) -> Self
818 where
819 I: Iterator<Item = Decimal<M>>,
820 {
821 iter.map(|v| v).collect::<Vec<_>>().iter().sum()
822 }
823}
824
825impl<'a, const M: usize, const N: usize> Sum<&'a Decimal<M>> for Decimal<N> {
826 fn sum<I>(iter: I) -> Self
827 where
828 I: Iterator<Item = &'a Decimal<M>>,
829 {
830 let mut cx = Context::<Self>::default();
831 cx.sum(iter)
832 }
833}
834
835impl<const M: usize, const N: usize> Product<Decimal<M>> for Decimal<N> {
836 fn product<I>(iter: I) -> Self
837 where
838 I: Iterator<Item = Decimal<M>>,
839 {
840 iter.map(|v| v).collect::<Vec<_>>().iter().product()
841 }
842}
843
844impl<'a, const M: usize, const N: usize> Product<&'a Decimal<M>> for Decimal<N> {
845 fn product<I>(iter: I) -> Self
846 where
847 I: Iterator<Item = &'a Decimal<M>>,
848 {
849 let mut cx = Context::<Self>::default();
850 cx.product(iter)
851 }
852}
853
854impl<const N: usize> fmt::Debug for Decimal<N> {
855 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
856 fmt::Display::fmt(self, f)
857 }
858}
859
860impl<const N: usize> fmt::Display for Decimal<N> {
861 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
862 let mut buf = Vec::with_capacity(self.digits as usize + 14);
865 let c_str = unsafe {
866 if f.alternate() {
867 decnumber_sys::decNumberToEngString(self.as_ptr(), buf.as_mut_ptr() as *mut c_char);
868 } else {
869 decnumber_sys::decNumberToString(self.as_ptr(), buf.as_mut_ptr() as *mut c_char);
870 }
871 CStr::from_ptr(buf.as_ptr() as *const c_char)
872 };
873 f.write_str(
874 c_str
875 .to_str()
876 .expect("decNumberToString yields valid UTF-8"),
877 )
878 }
879}
880
881impl<const N: usize> FromStr for Decimal<N> {
882 type Err = ParseDecimalError;
883
884 fn from_str(s: &str) -> Result<Decimal<N>, ParseDecimalError> {
885 Context::<Decimal<N>>::default().parse(s)
886 }
887}
888
889macro_rules! __decnum_tryinto_primitive {
892 ($p:ty, $cx:expr, $max_digits:literal, $d:expr, $allow_neg:expr) => {{
893 $cx.rescale(&mut $d, &Decimal::<N>::zero());
894
895 let inexact = $cx.status().inexact();
897
898 let mut fail = || -> TryFromDecimalError {
899 let mut s = $cx.status();
900 s.set_invalid_operation();
901 $cx.set_status(s);
902 TryFromDecimalError
903 };
904
905 if $d.is_special()
906 || $d.digits() > $max_digits
907 || (!$allow_neg && $d.is_negative())
908 || inexact
909 {
910 return Err(fail());
911 }
912
913 let accum_op = if $d.is_negative() {
914 <$p>::checked_sub
915 } else {
916 <$p>::checked_add
917 };
918 let ten: $p = 10;
919 let mut ten_pow = 0;
920
921 let mut accum = 0;
922 || -> Option<$p> {
924 for v in $d.coefficient_units() {
925 let d = <$p>::from(*v).checked_mul(ten.pow(ten_pow))?;
926 accum = accum_op(accum, d)?;
927 ten_pow += decnumber_sys::DECDPUN as u32;
928 }
929 Some(accum)
930 }()
931 .ok_or_else(|| fail())
932 }};
933}
934
935macro_rules! decnum_tryinto_primitive_int {
936 ($p:ty, $cx:expr, $max_digits:literal, $d:expr) => {{
937 __decnum_tryinto_primitive!($p, $cx, $max_digits, $d, true)
938 }};
939}
940
941macro_rules! decnum_tryinto_primitive_uint {
942 ($p:ty, $cx:expr, $max_digits:literal, $d:expr) => {{
943 __decnum_tryinto_primitive!($p, $cx, $max_digits, $d, false)
944 }};
945}
946
947impl<const N: usize> TryFrom<Decimal<N>> for i8 {
950 type Error = TryFromDecimalError;
951 fn try_from(n: Decimal<N>) -> Result<i8, Self::Error> {
952 let mut cx = Context::<Decimal<N>>::default();
953 cx.try_into_i8(n)
954 }
955}
956
957impl<const N: usize> TryFrom<Decimal<N>> for u8 {
960 type Error = TryFromDecimalError;
961 fn try_from(n: Decimal<N>) -> Result<u8, Self::Error> {
962 let mut cx = Context::<Decimal<N>>::default();
963 cx.try_into_u8(n)
964 }
965}
966
967impl<const N: usize> TryFrom<Decimal<N>> for i16 {
970 type Error = TryFromDecimalError;
971 fn try_from(n: Decimal<N>) -> Result<i16, Self::Error> {
972 let mut cx = Context::<Decimal<N>>::default();
973 cx.try_into_i16(n)
974 }
975}
976
977impl<const N: usize> TryFrom<Decimal<N>> for u16 {
980 type Error = TryFromDecimalError;
981 fn try_from(n: Decimal<N>) -> Result<u16, Self::Error> {
982 let mut cx = Context::<Decimal<N>>::default();
983 cx.try_into_u16(n)
984 }
985}
986
987impl<const N: usize> TryFrom<Decimal<N>> for i32 {
990 type Error = TryFromDecimalError;
991 fn try_from(n: Decimal<N>) -> Result<i32, Self::Error> {
992 let mut cx = Context::<Decimal<N>>::default();
993 cx.try_into_i32(n)
994 }
995}
996
997impl<const N: usize> TryFrom<Decimal<N>> for u32 {
1000 type Error = TryFromDecimalError;
1001 fn try_from(n: Decimal<N>) -> Result<u32, Self::Error> {
1002 let mut cx = Context::<Decimal<N>>::default();
1003 cx.try_into_u32(n)
1004 }
1005}
1006
1007impl<const N: usize> TryFrom<Decimal<N>> for i64 {
1010 type Error = TryFromDecimalError;
1011 fn try_from(n: Decimal<N>) -> Result<i64, Self::Error> {
1012 let mut cx = Context::<Decimal<N>>::default();
1013 cx.try_into_i64(n)
1014 }
1015}
1016
1017impl<const N: usize> TryFrom<Decimal<N>> for u64 {
1020 type Error = TryFromDecimalError;
1021 fn try_from(n: Decimal<N>) -> Result<u64, Self::Error> {
1022 let mut cx = Context::<Decimal<N>>::default();
1023 cx.try_into_u64(n)
1024 }
1025}
1026
1027impl<const N: usize> TryFrom<Decimal<N>> for i128 {
1030 type Error = TryFromDecimalError;
1031 fn try_from(n: Decimal<N>) -> Result<i128, Self::Error> {
1032 let mut cx = Context::<Decimal<N>>::default();
1033 cx.try_into_i128(n)
1034 }
1035}
1036
1037impl<const N: usize> TryFrom<Decimal<N>> for u128 {
1040 type Error = TryFromDecimalError;
1041 fn try_from(n: Decimal<N>) -> Result<u128, Self::Error> {
1042 let mut cx = Context::<Decimal<N>>::default();
1043 cx.try_into_u128(n)
1044 }
1045}
1046
1047impl<const N: usize> TryFrom<Decimal<N>> for usize {
1050 type Error = TryFromDecimalError;
1051 fn try_from(n: Decimal<N>) -> Result<usize, Self::Error> {
1052 let mut cx = Context::<Decimal<N>>::default();
1053 cx.try_into_usize(n)
1054 }
1055}
1056
1057impl<const N: usize> TryFrom<Decimal<N>> for isize {
1060 type Error = TryFromDecimalError;
1061 fn try_from(n: Decimal<N>) -> Result<isize, Self::Error> {
1062 let mut cx = Context::<Decimal<N>>::default();
1063 cx.try_into_isize(n)
1064 }
1065}
1066
1067macro_rules! decnum_tryinto_primitive_float {
1068 ($p:ty, $cx:expr, $d:expr) => {{
1069 if $d.is_infinite() {
1070 return Ok(if $d.is_negative() {
1071 <$p>::NEG_INFINITY
1072 } else {
1073 <$p>::INFINITY
1074 });
1075 }
1076 if $d.is_nan() {
1077 return Ok(<$p>::NAN);
1078 }
1079
1080 const TEN: $p = 10.0;
1081 const DECDPUN_F: $p = decnumber_sys::DECDPUN as $p;
1082
1083 let mut e = $d.exponent() as $p;
1084 let mut f: $p = 0.0;
1085 for u in $d.coefficient_units() {
1086 f += <$p>::from(*u) * TEN.powf(e);
1088 e += DECDPUN_F;
1089 }
1090 if $d.is_negative() {
1091 f = -f;
1092 }
1093
1094 if f.is_infinite() || f.is_nan() || (!$d.is_zero() && f == 0.0) {
1100 let mut s = $cx.status();
1101 s.set_invalid_operation();
1102 $cx.set_status(s);
1103 Err(TryFromDecimalError)
1104 } else {
1105 Ok(f)
1106 }
1107 }};
1108}
1109
1110impl<const N: usize> TryFrom<Decimal<N>> for f32 {
1111 type Error = TryFromDecimalError;
1112 fn try_from(n: Decimal<N>) -> Result<f32, Self::Error> {
1113 let mut cx = Context::<Decimal<N>>::default();
1114 cx.try_into_f32(n)
1115 }
1116}
1117
1118impl<const N: usize> TryFrom<Decimal<N>> for f64 {
1119 type Error = TryFromDecimalError;
1120 fn try_from(n: Decimal<N>) -> Result<f64, Self::Error> {
1121 let mut cx = Context::<Decimal<N>>::default();
1122 cx.try_into_f64(n)
1123 }
1124}
1125
1126impl<const N: usize> From<f32> for Decimal<N> {
1127 fn from(n: f32) -> Decimal<N> {
1128 let mut cx = Context::<Decimal<N>>::default();
1129 cx.from_f32(n)
1130 }
1131}
1132
1133impl<const N: usize> From<f64> for Decimal<N> {
1134 fn from(n: f64) -> Decimal<N> {
1135 let mut cx = Context::<Decimal<N>>::default();
1136 cx.from_f64(n)
1137 }
1138}
1139
1140impl<const N: usize> From<i8> for Decimal<N> {
1141 fn from(n: i8) -> Decimal<N> {
1142 Decimal::<N>::from(i32::from(n))
1143 }
1144}
1145
1146impl<const N: usize> From<u8> for Decimal<N> {
1147 fn from(n: u8) -> Decimal<N> {
1148 Decimal::<N>::from(u32::from(n))
1149 }
1150}
1151
1152impl<const N: usize> From<i16> for Decimal<N> {
1153 fn from(n: i16) -> Decimal<N> {
1154 Decimal::<N>::from(i32::from(n))
1155 }
1156}
1157
1158impl<const N: usize> From<u16> for Decimal<N> {
1159 fn from(n: u16) -> Decimal<N> {
1160 Decimal::<N>::from(u32::from(n))
1161 }
1162}
1163
1164impl<const N: usize> From<i32> for Decimal<N> {
1165 fn from(n: i32) -> Decimal<N> {
1166 let mut d = Decimal::default();
1167 unsafe {
1168 decnumber_sys::decNumberFromInt32(d.as_mut_ptr() as *mut decnumber_sys::decNumber, n);
1169 }
1170 d
1171 }
1172}
1173
1174impl<const N: usize> From<u32> for Decimal<N> {
1175 fn from(n: u32) -> Decimal<N> {
1176 let mut d = Decimal::default();
1177 unsafe {
1178 decnumber_sys::decNumberFromUInt32(d.as_mut_ptr() as *mut decnumber_sys::decNumber, n);
1179 }
1180 d
1181 }
1182}
1183
1184impl<const N: usize> From<i64> for Decimal<N> {
1185 fn from(n: i64) -> Decimal<N> {
1186 let mut cx = Context::<Decimal<N>>::default();
1187 cx.from_i64(n)
1188 }
1189}
1190
1191impl<const N: usize> From<u64> for Decimal<N> {
1192 fn from(n: u64) -> Decimal<N> {
1193 let mut cx = Context::<Decimal<N>>::default();
1194 cx.from_u64(n)
1195 }
1196}
1197
1198impl<const N: usize> TryFrom<i128> for Decimal<N> {
1204 type Error = TryIntoDecimalError;
1205 fn try_from(n: i128) -> Result<Decimal<N>, Self::Error> {
1206 let mut cx = Context::<Decimal<N>>::default();
1207 let d = cx.from_i128(n);
1208 return if cx.status().any() {
1209 Err(TryIntoDecimalError)
1210 } else {
1211 Ok(d)
1212 };
1213 }
1214}
1215
1216impl<const N: usize> TryFrom<u128> for Decimal<N> {
1222 type Error = TryIntoDecimalError;
1223 fn try_from(n: u128) -> Result<Decimal<N>, Self::Error> {
1224 let mut cx = Context::<Decimal<N>>::default();
1225 let d = cx.from_u128(n);
1226 return if cx.status().any() {
1227 Err(TryIntoDecimalError)
1228 } else {
1229 Ok(d)
1230 };
1231 }
1232}
1233
1234#[cfg(target_pointer_width = "32")]
1235impl<const N: usize> From<usize> for Decimal<N> {
1236 fn from(n: usize) -> Decimal<N> {
1237 Decimal::<N>::from(n as u32)
1238 }
1239}
1240
1241#[cfg(target_pointer_width = "32")]
1242impl<const N: usize> From<isize> for Decimal<N> {
1243 fn from(n: isize) -> Decimal<N> {
1244 Decimal::<N>::from(n as i32)
1245 }
1246}
1247
1248#[cfg(target_pointer_width = "64")]
1249impl<const N: usize> From<usize> for Decimal<N> {
1250 fn from(n: usize) -> Decimal<N> {
1251 Decimal::<N>::from(n as u64)
1252 }
1253}
1254
1255#[cfg(target_pointer_width = "64")]
1256impl<const N: usize> From<isize> for Decimal<N> {
1257 fn from(n: isize) -> Decimal<N> {
1258 Decimal::<N>::from(n as i64)
1259 }
1260}
1261
1262impl<const N: usize> From<Decimal32> for Decimal<N> {
1263 fn from(n: Decimal32) -> Decimal<N> {
1264 let mut d = Decimal::default();
1265 unsafe {
1266 decnumber_sys::decimal32ToNumber(
1267 &n.inner,
1268 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1269 );
1270 }
1271 d
1272 }
1273}
1274
1275impl<const N: usize> From<Decimal64> for Decimal<N> {
1276 fn from(n: Decimal64) -> Decimal<N> {
1277 let mut d = Decimal::default();
1278 unsafe {
1279 decnumber_sys::decimal64ToNumber(
1280 &n.inner,
1281 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1282 );
1283 }
1284 d
1285 }
1286}
1287
1288impl<const N: usize> From<Decimal128> for Decimal<N> {
1289 fn from(n: Decimal128) -> Decimal<N> {
1290 let mut d = Decimal::default();
1291 unsafe {
1292 decnumber_sys::decimal128ToNumber(
1293 &n.inner,
1294 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1295 );
1296 }
1297 d
1298 }
1299}
1300
1301impl<const N: usize> Default for Context<Decimal<N>> {
1302 fn default() -> Context<Decimal<N>> {
1303 let mut ctx = MaybeUninit::<decnumber_sys::decContext>::uninit();
1304 let mut ctx = unsafe {
1305 decnumber_sys::decContextDefault(ctx.as_mut_ptr(), decnumber_sys::DEC_INIT_BASE);
1306 ctx.assume_init()
1307 };
1308 ctx.traps = 0;
1309 ctx.digits = i32::try_from(N * decnumber_sys::DECDPUN)
1312 .expect("decimal digit count does not fit into i32");
1313 Context {
1314 inner: ctx,
1315 _phantom: PhantomData,
1316 }
1317 }
1318}
1319
1320impl<const N: usize> Context<Decimal<N>> {
1321 pub fn precision(&self) -> usize {
1326 usize::try_from(self.inner.digits).expect("context digit count does not fit into usize")
1327 }
1328
1329 pub fn set_precision(&mut self, precision: usize) -> Result<(), InvalidPrecisionError> {
1333 if precision < 1 || precision > N * decnumber_sys::DECDPUN {
1334 return Err(InvalidPrecisionError);
1335 }
1336 self.inner.digits = i32::try_from(precision).map_err(|_| InvalidPrecisionError)?;
1337 Ok(())
1338 }
1339
1340 pub fn clamp(&self) -> bool {
1347 self.inner.clamp != 0
1348 }
1349
1350 pub fn set_clamp(&mut self, clamp: bool) {
1352 self.inner.clamp = u8::from(clamp)
1353 }
1354
1355 pub fn max_exponent(&self) -> isize {
1362 isize::try_from(self.inner.emax).expect("context max exponent does not fit into isize")
1363 }
1364
1365 pub fn set_max_exponent(&mut self, e: isize) -> Result<(), InvalidExponentError> {
1370 if e < 0 || e > 999999999 {
1371 return Err(InvalidExponentError);
1372 }
1373 self.inner.emax = i32::try_from(e).map_err(|_| InvalidExponentError)?;
1374 Ok(())
1375 }
1376
1377 pub fn min_exponent(&self) -> isize {
1384 isize::try_from(self.inner.emin).expect("context min exponent does not fit into isize")
1385 }
1386
1387 pub fn set_min_exponent(&mut self, e: isize) -> Result<(), InvalidExponentError> {
1392 if e > 0 || e < -999999999 {
1393 return Err(InvalidExponentError);
1394 }
1395 self.inner.emin = i32::try_from(e).map_err(|_| InvalidExponentError)?;
1396 Ok(())
1397 }
1398
1399 pub fn parse<S>(&mut self, s: S) -> Result<Decimal<N>, ParseDecimalError>
1401 where
1402 S: Into<Vec<u8>>,
1403 {
1404 let c_string = CString::new(s).map_err(|_| ParseDecimalError)?;
1405 self.parse_c_str(c_string.as_c_str())
1406 }
1407
1408 pub fn parse_c_str(&mut self, s: &CStr) -> Result<Decimal<N>, ParseDecimalError> {
1410 validate_n(N);
1411 let mut d = Decimal::zero();
1412 unsafe {
1413 decnumber_sys::decNumberFromString(
1414 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1415 s.as_ptr(),
1416 &mut self.inner,
1417 );
1418 };
1419 if (self.inner.status & decnumber_sys::DEC_Conversion_syntax) != 0 {
1420 Err(ParseDecimalError)
1421 } else {
1422 Ok(d)
1423 }
1424 }
1425
1426 pub fn class(&mut self, n: &Decimal<N>) -> Class {
1428 Class::from_c(unsafe { decnumber_sys::decNumberClass(n.as_ptr(), &mut self.inner) })
1429 }
1430
1431 pub fn abs(&mut self, n: &mut Decimal<N>) {
1437 let n = n.as_mut_ptr();
1438 unsafe {
1439 decnumber_sys::decNumberAbs(n, n, &mut self.inner);
1440 }
1441 }
1442
1443 pub fn add<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1445 let lhs = lhs.as_mut_ptr();
1446 unsafe {
1447 decnumber_sys::decNumberAdd(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1448 }
1449 }
1450
1451 pub fn and<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1454 let lhs = lhs.as_mut_ptr();
1455 unsafe {
1456 decnumber_sys::decNumberAnd(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1457 }
1458 }
1459
1460 pub fn div<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1462 let lhs = lhs.as_mut_ptr();
1463 unsafe {
1464 decnumber_sys::decNumberDivide(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1465 }
1466 }
1467
1468 pub fn div_integer<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1470 let lhs = lhs.as_mut_ptr();
1471 unsafe {
1472 decnumber_sys::decNumberDivideInteger(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1473 }
1474 }
1475
1476 pub fn exp(&mut self, n: &mut Decimal<N>) {
1478 let n = n.as_mut_ptr();
1479 unsafe {
1480 decnumber_sys::decNumberExp(n, n, &mut self.inner);
1481 }
1482 }
1483
1484 pub fn fma<const L: usize, const M: usize>(
1490 &mut self,
1491 x: &mut Decimal<N>,
1492 y: &Decimal<L>,
1493 z: &Decimal<M>,
1494 ) {
1495 let x = x.as_mut_ptr();
1496 unsafe {
1497 decnumber_sys::decNumberFMA(x, x, y.as_ptr(), z.as_ptr(), &mut self.inner);
1498 }
1499 }
1500
1501 pub fn from_i32(&mut self, n: i32) -> Decimal<N> {
1503 Decimal::<N>::from(n)
1504 }
1505
1506 pub fn from_u32(&mut self, n: u32) -> Decimal<N> {
1508 Decimal::<N>::from(n)
1509 }
1510
1511 pub fn from_i64(&mut self, n: i64) -> Decimal<N> {
1513 decimal_from_signed_int!(self, n)
1514 }
1515
1516 pub fn from_u64(&mut self, n: u64) -> Decimal<N> {
1518 decimal_from_unsigned_int!(self, n)
1519 }
1520
1521 pub fn from_i128(&mut self, n: i128) -> Decimal<N> {
1549 decimal_from_signed_int!(self, n)
1550 }
1551
1552 pub fn from_u128(&mut self, n: u128) -> Decimal<N> {
1575 decimal_from_unsigned_int!(self, n)
1576 }
1577
1578 pub fn try_into_u8(&mut self, d: Decimal<N>) -> Result<u8, TryFromDecimalError> {
1583 let i = self.try_into_u32(d)?;
1584 u8::try_from(i).map_err(|_| TryFromDecimalError)
1585 }
1586
1587 pub fn try_into_i8(&mut self, d: Decimal<N>) -> Result<i8, TryFromDecimalError> {
1592 let i = self.try_into_i32(d)?;
1593 i8::try_from(i).map_err(|_| TryFromDecimalError)
1594 }
1595
1596 pub fn try_into_u16(&mut self, d: Decimal<N>) -> Result<u16, TryFromDecimalError> {
1601 let i = self.try_into_u32(d)?;
1602 u16::try_from(i).map_err(|_| TryFromDecimalError)
1603 }
1604
1605 pub fn try_into_i16(&mut self, d: Decimal<N>) -> Result<i16, TryFromDecimalError> {
1610 let i = self.try_into_i32(d)?;
1611 i16::try_from(i).map_err(|_| TryFromDecimalError)
1612 }
1613
1614 pub fn try_into_i32(&mut self, mut d: Decimal<N>) -> Result<i32, TryFromDecimalError> {
1629 self.rescale(&mut d, &Decimal::<N>::zero());
1630 let i = unsafe { decnumber_sys::decNumberToInt32(d.as_ptr(), &mut self.inner) };
1631 if self.status().invalid_operation() || self.status().inexact() {
1633 Err(TryFromDecimalError)
1634 } else {
1635 Ok(i)
1636 }
1637 }
1638
1639 pub fn try_into_u32(&mut self, mut d: Decimal<N>) -> Result<u32, TryFromDecimalError> {
1644 self.rescale(&mut d, &Decimal::<N>::zero());
1645 let i = unsafe { decnumber_sys::decNumberToUInt32(d.as_ptr(), &mut self.inner) };
1646 if self.status().invalid_operation() || self.status().inexact() {
1648 Err(TryFromDecimalError)
1649 } else {
1650 Ok(i)
1651 }
1652 }
1653
1654 #[cfg(target_pointer_width = "32")]
1659 pub fn try_into_isize(&mut self, d: Decimal<N>) -> Result<isize, TryFromDecimalError> {
1660 let d = self.try_into_i32(d)?;
1661 Ok(d as isize)
1662 }
1663
1664 #[cfg(target_pointer_width = "64")]
1669 pub fn try_into_isize(&mut self, d: Decimal<N>) -> Result<isize, TryFromDecimalError> {
1670 let d = self.try_into_i64(d)?;
1671 Ok(d as isize)
1672 }
1673
1674 pub fn try_into_i64(&mut self, mut d: Decimal<N>) -> Result<i64, TryFromDecimalError> {
1679 decnum_tryinto_primitive_int!(i64, self, 19, d)
1680 }
1681
1682 pub fn try_into_i128(&mut self, mut d: Decimal<N>) -> Result<i128, TryFromDecimalError> {
1687 decnum_tryinto_primitive_int!(i128, self, 39, d)
1688 }
1689
1690 #[cfg(target_pointer_width = "32")]
1695 pub fn try_into_usize(&mut self, d: Decimal<N>) -> Result<usize, TryFromDecimalError> {
1696 let d = self.try_into_u32(d)?;
1697 Ok(d as usize)
1698 }
1699
1700 #[cfg(target_pointer_width = "64")]
1705 pub fn try_into_usize(&mut self, d: Decimal<N>) -> Result<usize, TryFromDecimalError> {
1706 let d = self.try_into_u64(d)?;
1707 Ok(d as usize)
1708 }
1709
1710 pub fn try_into_u64(&mut self, mut d: Decimal<N>) -> Result<u64, TryFromDecimalError> {
1715 decnum_tryinto_primitive_uint!(u64, self, 20, d)
1716 }
1717
1718 pub fn try_into_u128(&mut self, mut d: Decimal<N>) -> Result<u128, TryFromDecimalError> {
1723 decnum_tryinto_primitive_uint!(u128, self, 39, d)
1724 }
1725
1726 pub fn try_into_f32(&mut self, d: Decimal<N>) -> Result<f32, TryFromDecimalError> {
1733 decnum_tryinto_primitive_float!(f32, self, d)
1734 }
1735
1736 pub fn try_into_f64(&mut self, d: Decimal<N>) -> Result<f64, TryFromDecimalError> {
1741 decnum_tryinto_primitive_float!(f64, self, d)
1742 }
1743
1744 pub fn from_f32(&mut self, n: f32) -> Decimal<N> {
1753 self.from_float(n)
1754 }
1755
1756 pub fn from_f64(&mut self, n: f64) -> Decimal<N> {
1765 self.from_float(n)
1766 }
1767
1768 pub fn from_float<T: LowerExp + Display>(&mut self, n: T) -> Decimal<N> {
1779 const MAX_LEN: usize = 1024;
1783
1784 let mut buf = [0u8; MAX_LEN + 1];
1786 let mut unwritten = &mut buf[..MAX_LEN];
1787 write!(unwritten, "{}", n).unwrap();
1788 let unwritten_len = unwritten.len();
1789 let c_buf =
1795 unsafe { CStr::from_bytes_with_nul_unchecked(&buf[..MAX_LEN - unwritten_len + 1]) };
1796 self.parse_c_str(c_buf).unwrap()
1797 }
1798
1799 pub fn invert(&mut self, n: &mut Decimal<N>) {
1802 let n = n.as_mut_ptr();
1803 unsafe {
1804 decnumber_sys::decNumberInvert(n, n, &mut self.inner);
1805 }
1806 }
1807
1808 pub fn ln(&mut self, n: &mut Decimal<N>) {
1810 let n = n.as_mut_ptr();
1811 unsafe {
1812 decnumber_sys::decNumberLn(n, n, &mut self.inner);
1813 }
1814 }
1815
1816 pub fn log10(&mut self, n: &mut Decimal<N>) {
1818 let n = n.as_mut_ptr();
1819 unsafe {
1820 decnumber_sys::decNumberLog10(n, n, &mut self.inner);
1821 }
1822 }
1823
1824 pub fn logb(&mut self, n: &mut Decimal<N>) {
1827 let n = n.as_mut_ptr();
1828 unsafe {
1829 decnumber_sys::decNumberLogB(n, n, &mut self.inner);
1830 }
1831 }
1832
1833 pub fn max<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1838 let lhs = lhs.as_mut_ptr();
1839 unsafe {
1840 decnumber_sys::decNumberMax(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1841 }
1842 }
1843
1844 pub fn max_abs<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1847 let lhs = lhs.as_mut_ptr();
1848 unsafe {
1849 decnumber_sys::decNumberMaxMag(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1850 }
1851 }
1852
1853 pub fn min<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1858 let lhs = lhs.as_mut_ptr();
1859 unsafe {
1860 decnumber_sys::decNumberMin(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1861 }
1862 }
1863
1864 pub fn min_abs<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1867 let lhs = lhs.as_mut_ptr();
1868 unsafe {
1869 decnumber_sys::decNumberMinMag(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1870 }
1871 }
1872
1873 pub fn minus(&mut self, n: &mut Decimal<N>) {
1875 unsafe {
1876 decnumber_sys::decNumberMinus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1877 }
1878 }
1879
1880 pub fn mul<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1882 let lhs = lhs.as_mut_ptr();
1883 unsafe {
1884 decnumber_sys::decNumberMultiply(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1885 }
1886 }
1887
1888 pub fn neg(&mut self, n: &mut Decimal<N>) {
1891 unsafe {
1892 decnumber_sys::decNumberCopyNegate(n.as_mut_ptr(), n.as_ptr());
1893 }
1894 }
1895
1896 pub fn next_minus(&mut self, n: &mut Decimal<N>) {
1901 unsafe {
1902 decnumber_sys::decNumberNextMinus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1903 }
1904 }
1905
1906 pub fn next_plus(&mut self, n: &mut Decimal<N>) {
1911 unsafe {
1912 decnumber_sys::decNumberNextPlus(n.as_mut_ptr(), n.as_ptr(), &mut self.inner);
1913 }
1914 }
1915
1916 pub fn next_toward<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
1922 unsafe {
1923 decnumber_sys::decNumberNextToward(
1924 x.as_mut_ptr(),
1925 x.as_ptr(),
1926 y.as_ptr(),
1927 &mut self.inner,
1928 );
1929 }
1930 }
1931
1932 pub fn or<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
1935 let lhs = lhs.as_mut_ptr();
1936 unsafe {
1937 decnumber_sys::decNumberOr(lhs, lhs, rhs.as_ptr(), &mut self.inner);
1938 }
1939 }
1940
1941 pub fn partial_cmp<const L: usize, const M: usize>(
1947 &mut self,
1948 lhs: &Decimal<L>,
1949 rhs: &Decimal<M>,
1950 ) -> Option<Ordering> {
1951 validate_n(N);
1952 let mut d = Decimal::<N>::zero();
1953 unsafe {
1954 decnumber_sys::decNumberCompare(
1955 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
1956 lhs.as_ptr(),
1957 rhs.as_ptr(),
1958 &mut self.inner,
1959 )
1960 };
1961 if d.is_nan() {
1962 None
1963 } else if d.is_negative() {
1964 Some(Ordering::Less)
1965 } else if d.is_zero() {
1966 Some(Ordering::Equal)
1967 } else {
1968 debug_assert!(!d.is_special());
1969 Some(Ordering::Greater)
1970 }
1971 }
1972
1973 pub fn plus(&mut self, n: &mut Decimal<N>) {
1975 let n = n.as_mut_ptr();
1976 unsafe {
1977 decnumber_sys::decNumberPlus(n, n, &mut self.inner);
1978 }
1979 }
1980
1981 pub fn pow<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
1983 let x = x.as_mut_ptr();
1984 unsafe {
1985 decnumber_sys::decNumberPower(x, x, y.as_ptr(), &mut self.inner);
1986 }
1987 }
1988
1989 pub fn product<'a, I, const M: usize>(&mut self, iter: I) -> Decimal<N>
1991 where
1992 I: Iterator<Item = &'a Decimal<M>>,
1993 {
1994 iter.fold(Decimal::<N>::from(1), |mut product, d| {
1995 self.mul(&mut product, &d);
1996 product
1997 })
1998 }
1999
2000 pub fn quantize<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2003 let lhs = lhs.as_mut_ptr();
2004 unsafe {
2005 decnumber_sys::decNumberQuantize(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2006 }
2007 }
2008
2009 pub fn reduce(&mut self, n: &mut Decimal<N>) {
2012 let n = n.as_mut_ptr();
2013 unsafe {
2014 decnumber_sys::decNumberReduce(n, n, &mut self.inner);
2015 }
2016 }
2017
2018 pub fn rem<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2020 let lhs = lhs.as_mut_ptr();
2021 unsafe {
2022 decnumber_sys::decNumberRemainder(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2023 }
2024 }
2025
2026 pub fn rem_near<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2029 let lhs = lhs.as_mut_ptr();
2030 unsafe {
2031 decnumber_sys::decNumberRemainderNear(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2032 }
2033 }
2034
2035 pub fn rescale<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2037 let lhs = lhs.as_mut_ptr();
2038 unsafe {
2039 decnumber_sys::decNumberRescale(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2040 }
2041 }
2042
2043 pub fn round(&mut self, n: &mut Decimal<N>) {
2046 let n = n.as_mut_ptr();
2047 unsafe {
2048 decnumber_sys::decNumberToIntegralExact(n, n, &mut self.inner);
2049 }
2050 }
2051
2052 pub fn round_to_place(
2061 &mut self,
2062 n: &mut Decimal<N>,
2063 place: usize,
2064 ) -> Result<(), InvalidPrecisionError> {
2065 let precision = self.precision();
2066 self.set_precision(place)?;
2067 self.plus(n);
2068 self.set_precision(precision)
2069 }
2070
2071 pub fn round_reduce_to_place(
2074 &mut self,
2075 n: &mut Decimal<N>,
2076 place: usize,
2077 ) -> Result<(), InvalidPrecisionError> {
2078 let precision = self.precision();
2079 self.set_precision(place)?;
2080 self.reduce(n);
2081 self.set_precision(precision)
2082 }
2083
2084 pub fn shift<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2092 let lhs = lhs.as_mut_ptr();
2093 unsafe {
2094 decnumber_sys::decNumberShift(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2095 }
2096 }
2097
2098 pub fn rotate<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2106 let lhs = lhs.as_mut_ptr();
2107 unsafe {
2108 decnumber_sys::decNumberRotate(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2109 }
2110 }
2111
2112 pub fn scaleb<const M: usize>(&mut self, x: &mut Decimal<N>, y: &Decimal<M>) {
2114 unsafe {
2115 decnumber_sys::decNumberScaleB(x.as_mut_ptr(), x.as_ptr(), y.as_ptr(), &mut self.inner);
2116 }
2117 }
2118
2119 pub fn sqrt<const M: usize>(&mut self, n: &mut Decimal<M>) {
2121 let n = n.as_mut_ptr();
2122 unsafe {
2123 decnumber_sys::decNumberSquareRoot(n, n, &mut self.inner);
2124 }
2125 }
2126
2127 pub fn sub<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2129 let lhs = lhs.as_mut_ptr();
2130 unsafe {
2131 decnumber_sys::decNumberSubtract(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2132 }
2133 }
2134
2135 pub fn sum<'a, I, const M: usize>(&mut self, iter: I) -> Decimal<N>
2137 where
2138 I: Iterator<Item = &'a Decimal<M>>,
2139 {
2140 iter.fold(Decimal::<N>::zero(), |mut sum, d| {
2141 self.add(&mut sum, d);
2142 sum
2143 })
2144 }
2145
2146 pub fn total_cmp<const L: usize, const M: usize>(
2151 &mut self,
2152 lhs: &Decimal<L>,
2153 rhs: &Decimal<M>,
2154 ) -> Ordering {
2155 validate_n(N);
2156 let mut d = Decimal::<N>::zero();
2157 unsafe {
2158 decnumber_sys::decNumberCompareTotal(
2159 d.as_mut_ptr() as *mut decnumber_sys::decNumber,
2160 lhs.as_ptr(),
2161 rhs.as_ptr(),
2162 &mut self.inner,
2163 )
2164 };
2165 debug_assert!(!d.is_special());
2166 if d.is_negative() {
2167 Ordering::Less
2168 } else if d.is_zero() {
2169 Ordering::Equal
2170 } else {
2171 Ordering::Greater
2172 }
2173 }
2174
2175 pub fn xor<const M: usize>(&mut self, lhs: &mut Decimal<N>, rhs: &Decimal<M>) {
2178 let lhs = lhs.as_mut_ptr();
2179 unsafe {
2180 decnumber_sys::decNumberXor(lhs, lhs, rhs.as_ptr(), &mut self.inner);
2181 }
2182 }
2183
2184 pub fn to_width<const M: usize>(&mut self, m: Decimal<M>) -> Decimal<N> {
2189 let mut n = Decimal::<N>::zero();
2190 unsafe {
2191 decnumber_sys::decNumberPlus(n.as_mut_ptr(), m.as_ptr(), &mut self.inner);
2192 }
2193 n
2194 }
2195}
2196
2197#[cfg(feature = "num-traits")]
2198impl<const N: usize> Zero for Decimal<N> {
2199 #[inline]
2200 fn zero() -> Self {
2201 Decimal::<N>::zero()
2202 }
2203
2204 #[inline]
2205 fn is_zero(&self) -> bool {
2206 self.is_zero()
2207 }
2208}
2209
2210#[cfg(feature = "num-traits")]
2211impl<const N: usize, const L: usize, const M: usize> MulAdd<Decimal<L>, Decimal<M>> for Decimal<N> {
2212 type Output = Self;
2213
2214 #[inline]
2215 fn mul_add(mut self, a: Decimal<L>, b: Decimal<M>) -> Self::Output {
2216 self.mul_add_assign(a, b);
2217 self
2218 }
2219}
2220
2221#[cfg(feature = "num-traits")]
2222impl<const N: usize, const L: usize, const M: usize> MulAddAssign<Decimal<L>, Decimal<M>>
2223 for Decimal<N>
2224{
2225 fn mul_add_assign(&mut self, a: Decimal<L>, b: Decimal<M>) {
2226 Context::<Self>::default().fma(self, &a, &b);
2227 }
2228}
2229
2230#[cfg(feature = "num-traits")]
2231impl<const N: usize, const M: usize> Pow<Decimal<M>> for Decimal<N> {
2232 type Output = Self;
2233
2234 fn pow(mut self, rhs: Decimal<M>) -> Self::Output {
2235 Context::<Decimal<N>>::default().pow(&mut self, &rhs);
2236
2237 self
2238 }
2239}