dec/
decimal.rs

1// Copyright Materialize, Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use 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    // TODO(benesch): check this at compile time, when that becomes possible.
45    if n < 12 || n > 999_999_999 {
46        panic!("Decimal<N>:: N is not in the range [12, 999999999]");
47    }
48}
49
50/// An arbitrary-precision decimal number.
51///
52/// The maximum number of digits that can be stored in the number is specified
53/// by `N * 3`. For example, a value of type `Decimal<3>` has space for nine
54/// decimal digits. This somewhat odd design is due to limitations of constant
55/// generic parameters in Rust. The intention is to someday make `N` correspond
56/// directly to the number of digits of precision.
57///
58/// `N` must be at least 12 and no greater than 999,999,999, though typically
59/// the stack size implies a smaller maximum for `N`. Due to limitations with
60/// constant generics it is not yet possible to enforce these restrictions at
61/// compile time, so they are checked at runtime.
62///
63/// For more details about e.g. the struct's fields, see the [upstream
64/// documentation](http://speleotrove.com/decimal/dnnumb.html).
65#[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    /// Must provide custom serde implementation for array defined with const
73    /// generic until something happens with
74    /// https://github.com/serde-rs/serde/issues/1272
75    #[cfg_attr(feature = "serde", serde(with = "lsu_serde"))]
76    pub(crate) lsu: [u16; N],
77}
78
79#[cfg(feature = "serde")]
80/// Provides a target for `serde(with = ...)` that permits deserializing `Decimal` values from
81/// primitive integers, `Strings`, or `str`.
82///
83/// ```rust
84/// use std::convert::TryFrom;
85/// use serde::{Deserialize, Serialize};
86/// const N: usize = 12;
87///
88/// #[repr(transparent)]
89/// #[derive(Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
90/// pub struct PrimitiveDeserializableDecimal<const N: usize>(
91///     #[serde(with = "dec::serde_decimal_from_non_float_primitives")] pub dec::Decimal<N>,
92/// );
93///
94/// let v: PrimitiveDeserializableDecimal<N> =
95///           serde_json::from_str("-1").expect("deserialization works");
96///
97/// assert_eq!(dec::Decimal::try_from(-1i32).unwrap(), v.0);
98/// ```
99///
100/// Note that the feature provided by this crate is only compatible with self-describing input
101/// formats, such as `JSON`, as it relies on [`Deserialize::deserialize_any`](deserialize_any).
102///
103/// [deserialize_any]:
104///     https://docs.rs/serde/latest/serde/trait.Deserializer.html#tymethod.deserialize_any
105pub 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    /// Serialize `d` using the default, derivsed `Serialize` implementation.
116    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    /// Deserializes the value permitting a conversion to a `Decimal<N>` from primitive integers
125    /// (`i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`), `String`, and `str`.
126    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    // Make this error checking shareable with manual deserialization impls.
322    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    /// Constructs a decimal number with `N / 3` digits of precision
345    /// representing the number 0.
346    pub fn zero() -> Decimal<N> {
347        Decimal::default()
348    }
349
350    /// Constructs a decimal number representing positive infinity.
351    pub fn infinity() -> Decimal<N> {
352        let mut d = Decimal::default();
353        d.bits = decnumber_sys::DECINF;
354        d
355    }
356
357    /// Constructs a decimal number representing a non-signaling NaN.
358    pub fn nan() -> Decimal<N> {
359        let mut d = Decimal::default();
360        d.bits = decnumber_sys::DECNAN;
361        d
362    }
363
364    // Constructs a decimal number equal to 2^32. We use this value internally
365    // to create decimals from primitive integers with more than 32 bits.
366    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    /// Computes the number of significant digits in the number.
374    ///
375    /// If the number is zero or infinite, returns 1. If the number is a NaN,
376    /// returns the number of digits in the payload.
377    pub fn digits(&self) -> u32 {
378        self.digits
379    }
380
381    /// Returns the individual digits of the coefficient in 8-bit, unpacked
382    /// [binary-coded decimal][bcd] format.
383    ///
384    /// [bcd]: https://en.wikipedia.org/wiki/Binary-coded_decimal
385    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    /// Returns the digits of the coefficient in [`decNumberUnit`][dnu] format,
394    /// which is a vector of `u16`, with element number representing
395    /// [`decnumber_sys::DECDPUN`] digits of the coefficient.
396    ///
397    /// The result is ordered with the least significant digits at index 0.
398    ///
399    /// [dpd]: http://speleotrove.com/decimal/dnnumb.html
400    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    /// Returns the value's coefficient as `T` or errors if not possible.
406    ///
407    /// All primitive ints are valid for `T`.
408    pub fn coefficient<T>(&mut self) -> Result<T, InvalidCoefficientError>
409    where
410        T: TryFrom<Decimal<N>>,
411    {
412        // Save current exponent to avoid an allocation.
413        let cur_exp = self.exponent();
414        // Temporarily set exponent to 0 to make convertible to primitive int
415        // `T`.
416        self.set_exponent(0);
417        let coefficient = <T>::try_from(*self);
418        // Revert the exponent to its previous value.
419        self.set_exponent(cur_exp);
420        match coefficient {
421            Ok(d) => Ok(d),
422            Err(_) => Err(InvalidCoefficientError),
423        }
424    }
425
426    /// Returns the number of elements required in the `lsu` to represent some
427    /// number of digits.
428    ///
429    /// This function is public and accepts a `u32` instead of a `Decimal` to
430    /// aid in recomposing ([`Self::from_raw_parts`]) values.
431    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    /// Computes the exponent of the number.
436    pub fn exponent(&self) -> i32 {
437        self.exponent
438    }
439
440    /// Sets `self`'s exponent to the provided value.
441    pub fn set_exponent(&mut self, exponent: i32) {
442        self.exponent = exponent;
443    }
444
445    /// Reports whether the number is finite.
446    ///
447    /// A finite number is one that is neither infinite nor a NaN.
448    pub fn is_finite(&self) -> bool {
449        (self.bits & decnumber_sys::DECSPECIAL) == 0
450    }
451
452    /// Reports whether the number is positive or negative infinity.
453    pub fn is_infinite(&self) -> bool {
454        (self.bits & decnumber_sys::DECINF) != 0
455    }
456
457    /// Reports whether the number is a NaN.
458    pub fn is_nan(&self) -> bool {
459        (self.bits & (decnumber_sys::DECNAN | decnumber_sys::DECSNAN)) != 0
460    }
461
462    /// Reports whether the number is negative.
463    ///
464    /// A negative number is either negative zero, less than zero, or NaN
465    /// with a sign of one. This corresponds to [`Decimal128::is_signed`], not
466    /// [`Decimal128::is_negative`].
467    pub fn is_negative(&self) -> bool {
468        (self.bits & decnumber_sys::DECNEG) != 0
469    }
470
471    /// Reports whether the number is a quiet NaN.
472    pub fn is_quiet_nan(&self) -> bool {
473        (self.bits & decnumber_sys::DECNAN) != 0
474    }
475
476    /// Reports whether the number is a signaling NaN.
477    pub fn is_signaling_nan(&self) -> bool {
478        (self.bits & decnumber_sys::DECSNAN) != 0
479    }
480
481    /// Reports whether the number has a special value.
482    ///
483    /// A special value is either infinity or NaN. This is the inverse of
484    /// [`Decimal::is_finite`].
485    pub fn is_special(&self) -> bool {
486        (self.bits & decnumber_sys::DECSPECIAL) != 0
487    }
488
489    /// Reports whether the number is positive or negative zero.
490    pub fn is_zero(&self) -> bool {
491        self.is_finite() && self.lsu[0] == 0 && self.digits == 1
492    }
493
494    /// Reports whether the quantum of the number matches the quantum of
495    /// `rhs`.
496    ///
497    /// Quantums are considered to match if the numbers have the same exponent,
498    /// are both NaNs, or both infinite.
499    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    /// Converts this decimal to a 32-bit decimal float.
517    ///
518    /// The result may be inexact. Use [`Context::<Decimal32>::from_decimal`]
519    /// to observe exceptional conditions.
520    pub fn to_decimal32(&self) -> Decimal32 {
521        Context::<Decimal32>::default().from_decimal(self)
522    }
523
524    /// Converts this decimal to a 64-bit decimal float.
525    ///
526    /// The result may be inexact. Use [`Context::<Decimal64>::from_decimal`]
527    /// to observe exceptional conditions.
528    pub fn to_decimal64(&self) -> Decimal64 {
529        Context::<Decimal64>::default().from_decimal(self)
530    }
531
532    /// Converts this decimal to a 128-bit decimal float.
533    ///
534    /// The result may be inexact. Use [`Context::<Decimal128>::from_decimal`]
535    /// to observe exceptional conditions.
536    pub fn to_decimal128(&self) -> Decimal128 {
537        Context::<Decimal128>::default().from_decimal(self)
538    }
539
540    /// Returns the raw parts of this decimal.
541    ///
542    /// The meaning of these parts are unspecified and subject to change. The
543    /// only guarantee is that these parts can be supplied as arguments to the
544    /// [`Decimal::from_raw_parts`] to produce a decimal equivalent to the
545    /// original.
546    pub fn to_raw_parts(&self) -> (u32, i32, u8, [u16; N]) {
547        (self.digits, self.exponent, self.bits, self.lsu)
548    }
549
550    /// Returns a `Decimal::<N>` with the supplied raw parts, which should be
551    /// generated using [`Decimal::to_raw_parts`].
552    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    /// Returns `self` as a [Packed Decimal][pd] number, including its scale
562    /// (i.e. its negated exponent) or `None` for special values.
563    ///
564    /// [pd]: http://speleotrove.com/decimal/dnpack.html
565    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            // Ensure space for sign nibble
572            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        // Null returned only for special values (already handled) or if `self`
586        // didn't fit within `bcd` (shouldn't happen).
587        assert!(!ret.is_null());
588        Some((bcd, scale))
589    }
590
591    /// Takes [Packed Decimal][pd] values and their scales (generated by
592    /// [`Self::to_packed_bcd`]) and returns a `Decimal`.
593    ///
594    /// # Errors
595    ///
596    /// - `bcd` contains more digits than the coefficient permits
597    /// - The adjusted exponent is out of range
598    /// - No sign nibble was found
599    /// - A sign nibble was found before the final nibble
600    ///
601    /// [pd]: http://speleotrove.com/decimal/dnpack.html
602    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    /// Returns a string of the number in standard notation, i.e. guaranteed to
621    /// not be scientific notation.
622    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        // We allocate space for all the digits plus a possible "-0." prefix.
637        // This is usually an overestimate but is an underestimate for very
638        // large or very small scales.
639        let mut out = String::with_capacity(digits.len() + 3);
640        if self.is_negative() {
641            out.push('-');
642        }
643
644        if e >= 0 {
645            // All digits before the decimal point.
646            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            // Digits span the decimal point.
656            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            // All digits after the decimal point.
666            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    /// Removes insignificant trailing zeros from a number, unconditionally, and
678    /// stores the modified value in `self`.
679    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    /// Note that this clones `self` to generate the negative value. For a
714    /// non-cloning method, use `Context::<N>::neg`.
715    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    /// Note that this clones `self` to generate the output. For a
729    /// non-cloning method, use `Context::<N>::add`.
730    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    /// Note that this clones `self` to generate the output. For a
747    /// non-cloning method, use `Context::<N>::div`.
748    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    /// Note that this clones `self` to generate the output. For a
765    /// non-cloning method, use `Context::<N>::mul`.
766    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    /// Note that this clones `self` to generate the output. For a
783    /// non-cloning method, use `Context::<N>::rem`.
784    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    /// Note that this clones `self` to generate the output. For a
801    /// non-cloning method, use `Context::<N>::sub`.
802    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        // String conversion may need up to `self.digits + 14` characters,
862        // per the libdecnumber documentation.
863        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
888/// Implements `std::convert::TryInto` semantics for `Decimal<N>` (represented
889/// by `$d`) into primitive integers (`$p`).
890macro_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        // inexact indicates you rounded away non-zero digits during rescale.
895        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        // try-catch
922        || -> 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
946/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
947/// this trait.
948impl<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
956/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
957/// this trait.
958impl<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
966/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
967/// this trait.
968impl<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
976/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
977/// this trait.
978impl<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
986/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
987/// this trait.
988impl<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
996/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
997/// this trait.
998impl<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
1006/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1007/// this trait.
1008impl<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
1016/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1017/// this trait.
1018impl<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
1026/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1027/// this trait.
1028impl<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
1036/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1037/// this trait.
1038impl<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
1046/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1047/// this trait.
1048impl<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
1056/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1057/// this trait.
1058impl<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            // `powi` gives wrong results on some input, whereas `powf` does not
1086            f += <$p>::from(*u) * TEN.powf(e);
1087            e += DECDPUN_F;
1088        }
1089        if $d.is_negative() {
1090            f = -f;
1091        }
1092
1093        // Value over- or underflows $p:
1094        // - f.is_infinite() represents generic overflow
1095        // - f.is_nan() can occur when multiplying a coefficient unit by a power
1096        //   of 10 that exceeds the primitive type's maximum exponent
1097        // - (!$d.is_zero() && f == 0.0) represents underflow
1098        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
1197/// Generates a [`Decimal`] from an `i128` or fails if the result would be
1198/// imprecise, e.g. has more than `N*3` digits of precision.
1199///
1200/// For an infallible version of this function, see
1201/// [`Context<Decimal<N>>::from_i128`].
1202impl<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
1215/// Generates a [`Decimal`] from a `u128` or fails if the result would be
1216/// imprecise, e.g. has more than `N*3` digits of precision.
1217///
1218/// For an infallible version of this function, see
1219/// [`Context<Decimal<N>>::from_u128`].
1220impl<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        // TODO(benesch): this could be a static assertion or a where bound,
1309        // if either of those were supported.
1310        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    /// Returns the context's precision.
1321    ///
1322    /// Operations that use this context will be rounded to this length if
1323    /// necessary.
1324    pub fn precision(&self) -> usize {
1325        usize::try_from(self.inner.digits).expect("context digit count does not fit into usize")
1326    }
1327
1328    /// Sets the context's precision.
1329    ///
1330    /// The precision must be at least one and no greater than `N * 3`.
1331    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    /// Reports whether the context has exponent clamping enabled.
1340    ///
1341    /// See the `clamp` field in the documentation of libdecnumber's
1342    /// [decContext module] for details.
1343    ///
1344    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1345    pub fn clamp(&self) -> bool {
1346        self.inner.clamp != 0
1347    }
1348
1349    /// Sets whether the context has exponent clamping enabled.
1350    pub fn set_clamp(&mut self, clamp: bool) {
1351        self.inner.clamp = u8::from(clamp)
1352    }
1353
1354    /// Returns the context's maximum exponent.
1355    ///
1356    /// See the `emax` field in the documentation of libdecnumber's
1357    /// [decContext module] for details.
1358    ///
1359    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1360    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    /// Sets the context's maximum exponent.
1365    ///
1366    /// The maximum exponent must not be negative and no greater than
1367    /// 999,999,999.
1368    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    /// Returns the context's minimum exponent.
1377    ///
1378    /// See the `emin` field in the documentation of libdecnumber's
1379    /// [decContext module] for details.
1380    ///
1381    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1382    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    /// Sets the context's minimum exponent.
1387    ///
1388    /// The minimum exponent must not be positive and no smaller than
1389    /// -999,999,999.
1390    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    /// Parses a number from its string representation.
1399    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    /// Classifies the number.
1421    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    /// Computes the absolute value of `n`, storing the result in `n`.
1426    ///
1427    /// This has the same effect as [`Context::<Decimal<N>>::plus`] unless
1428    /// `n` is negative, in which case it has the same effect as
1429    /// [`Context::<Decimal<N>>::minus`].
1430    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    /// Adds `lhs` and `rhs`, storing the result in `lhs`.
1438    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    /// Carries out the digitwise logical and of `lhs` and `rhs`, storing
1446    /// the result in `lhs`.
1447    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    /// Divides `lhs` by `rhs`, storing the result in `lhs`.
1455    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    /// Divides `lhs` by `rhs`, storing the integer part of the result in `lhs`.
1463    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    /// Raises *e* to the power of `n`, storing the result in `n`.
1471    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    /// Calculates the fused multiply-add `(x * y) + z` and stores the result
1479    /// in `x`.
1480    ///
1481    /// The multiplication is carried out first and is exact, so this operation
1482    /// only has the one, final rounding.
1483    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    /// Constructs a number from an `i32`.
1496    pub fn from_i32(&mut self, n: i32) -> Decimal<N> {
1497        Decimal::<N>::from(n)
1498    }
1499
1500    /// Constructs a number from an `i32`.
1501    pub fn from_u32(&mut self, n: u32) -> Decimal<N> {
1502        Decimal::<N>::from(n)
1503    }
1504
1505    /// Constructs a number from an `i64`.
1506    pub fn from_i64(&mut self, n: i64) -> Decimal<N> {
1507        decimal_from_signed_int!(self, n)
1508    }
1509
1510    /// Constructs a number from a `u64`.
1511    pub fn from_u64(&mut self, n: u64) -> Decimal<N> {
1512        decimal_from_unsigned_int!(self, n)
1513    }
1514
1515    /// Constructs a number from an `i128`.
1516    ///
1517    /// Note that this function can return inexact results for numbers with more
1518    /// than `N` * 3 places of precision, e.g. where `N` is 12,
1519    /// `9_999_999_999_999_999_999_999_999_999_999_999_999i128`,
1520    /// `-9_999_999_999_999_999_999_999_999_999_999_999_999i128`, `i128::MAX`,
1521    /// `i128::MIN`, etc.
1522    ///
1523    /// However, some numbers more than `N` * 3 places of precision retain their
1524    /// exactness, e.g. `1_000_000_000_000_000_000_000_000_000_000_000_000i128`.
1525    ///
1526    /// ```
1527    /// const N: usize = 12;
1528    /// use dec::Decimal;
1529    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1530    /// let d = ctx.from_i128(i128::MAX);
1531    /// // Inexact result
1532    /// assert!(ctx.status().inexact());
1533    ///
1534    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1535    /// let d = ctx.from_i128(1_000_000_000_000_000_000_000_000_000_000_000_000i128);
1536    /// // Exact result
1537    /// assert!(!ctx.status().inexact());
1538    /// ```
1539    ///
1540    /// To avoid inexact results when converting from large `i64`, use
1541    /// [`crate::Decimal128`] instead.
1542    pub fn from_i128(&mut self, n: i128) -> Decimal<N> {
1543        decimal_from_signed_int!(self, n)
1544    }
1545
1546    /// Constructs a number from an `u128`.
1547    ///
1548    /// Note that this function can return inexact results for numbers with more
1549    /// than `N` * 3 places of precision, e.g. where `N` is 12,
1550    /// `10_000_000_000_000_000_000_000_000_000_000_001u128` and `u128::MAX`.
1551    ///
1552    /// However, some numbers more than `N` * 3 places of precision retain their
1553    /// exactness,  e.g. `10_000_000_000_000_000_000_000_000_000_000_000u128`.
1554    ///
1555    /// ```
1556    /// const N: usize = 12;
1557    /// use dec::Decimal;
1558    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1559    /// let d = ctx.from_u128(u128::MAX);
1560    /// // Inexact result
1561    /// assert!(ctx.status().inexact());
1562    ///
1563    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1564    /// let d = ctx.from_u128(1_000_000_000_000_000_000_000_000_000_000_000_000u128);
1565    /// // Exact result
1566    /// assert!(!ctx.status().inexact());
1567    /// ```
1568    pub fn from_u128(&mut self, n: u128) -> Decimal<N> {
1569        decimal_from_unsigned_int!(self, n)
1570    }
1571
1572    /// Attempts to convert `d` to `u8` or fails if not possible.
1573    ///
1574    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1575    /// function.
1576    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    /// Attempts to convert `d` to `i8` or fails if not possible.
1582    ///
1583    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1584    /// function.
1585    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    /// Attempts to convert `d` to `u16` or fails if not possible.
1591    ///
1592    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1593    /// function.
1594    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    /// Attempts to convert `d` to `i16` or fails if not possible.
1600    ///
1601    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1602    /// function.
1603    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    /// Attempts to convert `d` to `i32` or fails if not possible. Note that
1609    /// when returning an error, `self`'s [`context::Status`] is set to
1610    /// `invalid_operation` in addition to using Rust's `Err` return value.
1611    ///
1612    /// Note that this function:
1613    /// - Accepts any value that can be rescaled to an exponent of 0 without
1614    ///   becoming inexact. For example, `123.000` and `123E2` are valid
1615    ///   `Decimal` values.
1616    ///
1617    ///   The corollary is that values that cannot be rescaled to an exponent of
1618    ///   0 error.
1619    /// - Errors if `self.status()` is set to `invalid_operation` irrespective
1620    ///   of whether or not this specific invocation of the function set that
1621    ///   status.
1622    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        // inexact indicates you rounded away non-zero digits during rescale.
1626        if self.status().invalid_operation() || self.status().inexact() {
1627            Err(TryFromDecimalError)
1628        } else {
1629            Ok(i)
1630        }
1631    }
1632
1633    /// Attempts to convert `d` to `u32` or fails if not possible.
1634    ///
1635    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1636    /// function.
1637    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        // inexact indicates you rounded away non-zero digits during rescale.
1641        if self.status().invalid_operation() || self.status().inexact() {
1642            Err(TryFromDecimalError)
1643        } else {
1644            Ok(i)
1645        }
1646    }
1647
1648    /// Attempts to convert `d` to `isize` or fails if not possible.
1649    ///
1650    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1651    /// function.
1652    #[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    /// Attempts to convert `d` to `isize` or fails if not possible.
1659    ///
1660    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1661    /// function.
1662    #[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    /// Attempts to convert `d` to `i64` or fails if not possible.
1669    ///
1670    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1671    /// function.
1672    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    /// Attempts to convert `d` to `i128` or fails if not possible.
1677    ///
1678    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1679    /// function.
1680    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    /// Attempts to convert `d` to `usize` or fails if not possible.
1685    ///
1686    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1687    /// function.
1688    #[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    /// Attempts to convert `d` to `usize` or fails if not possible.
1695    ///
1696    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1697    /// function.
1698    #[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    /// Attempts to convert `d` to `u64` or fails if not possible.
1705    ///
1706    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1707    /// function.
1708    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    /// Attempts to convert `d` to `u128` or fails if not possible.
1713    ///
1714    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1715    /// function.
1716    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    /// Attempts to convert `d` to `f32` or fails if not possible.
1721    ///
1722    /// Note that this function:
1723    /// - Errors for values that over- or underflow `f32`, rather than returning
1724    ///   infinity or `0.0`, respectively.
1725    /// - Returns a primitive infinity or NaN if `d` is an equivalent value.
1726    pub fn try_into_f32(&mut self, d: Decimal<N>) -> Result<f32, TryFromDecimalError> {
1727        decnum_tryinto_primitive_float!(f32, self, d)
1728    }
1729
1730    /// Attempts to convert `d` to `f32` or fails if not possible.
1731    ///
1732    /// Refer to the comments on [`Self::try_into_f32()`], which also apply to this
1733    /// function.
1734    pub fn try_into_f64(&mut self, d: Decimal<N>) -> Result<f64, TryFromDecimalError> {
1735        decnum_tryinto_primitive_float!(f64, self, d)
1736    }
1737
1738    /// Converts an `f32` to a `Decimal<N>`.
1739    ///
1740    /// Note that this conversion is infallible because `f32`'s:
1741    /// - Maximum precision is ~8
1742    /// - Min/max exponent is ~ -37, 37
1743    ///
1744    /// Both of these are guaranteed to fit comfortably within `Decimal`'s
1745    /// constraints.
1746    pub fn from_f32(&mut self, n: f32) -> Decimal<N> {
1747        self.parse(n.to_string().as_str()).unwrap()
1748    }
1749
1750    /// Converts an `f64` to a `Decimal<N>`.
1751    ///
1752    /// Note that this conversion is infallible because `f64`'s:
1753    /// - Maximum precision is ~18
1754    /// - Min/max exponent is ~ -305, 305
1755    ///
1756    /// Both of these are guaranteed to fit comfortably within `Decimal`'s
1757    /// constraints.
1758    pub fn from_f64(&mut self, n: f64) -> Decimal<N> {
1759        self.parse(n.to_string().as_str()).unwrap()
1760    }
1761
1762    /// Computes the digitwise logical inversion of `n`, storing the result in
1763    /// `n`.
1764    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    /// Computes the natural logarithm of `n`, storing the result in `n`.
1772    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    /// Computes the base-10 logarithm of `n`, storing the result in `n`.
1780    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    /// Computes the adjusted exponent of the number, according to IEEE 754
1788    /// rules.
1789    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    /// Places whichever of `lhs` and `rhs` is larger in `lhs`.
1797    ///
1798    /// The comparison is performed using the same rules as for
1799    /// [`total_cmp`](Context::<Decimal128>::total_cmp).
1800    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    /// Places whichever of `lhs` and `rhs` has the larger absolute value in
1808    /// `lhs`.
1809    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    /// Places whichever of `lhs` and `rhs` is smaller in `lhs`.
1817    ///
1818    /// The comparison is performed using the same rules as for
1819    /// [`total_cmp`](Context::<Decimal128>::total_cmp).
1820    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    /// Places whichever of `lhs` and `rhs` has the smaller absolute value in
1828    /// `lhs`.
1829    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    /// Subtracts `n` from zero, storing the result in `n`.
1837    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    /// Multiples `lhs` by `rhs`, storing the result in `lhs`.
1844    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    /// Negates the sign of `n`, storing the result in `n`. Note that unlike
1852    /// `minus`, no exception or error can occur.
1853    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    /// Computes the next number to `n` in the direction of negative infinity,
1860    /// storing the result in `n`.
1861    ///
1862    /// This operation is a generalization of the IEEE 754 *nextDown* operation.
1863    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    /// Computes the next number to `n` in the direction of positive infinity,
1870    /// storing the result in `n`.
1871    ///
1872    /// This operation is a generalization of the IEEE 754 *nextUp* operation.
1873    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    /// Computes the next number to `x` in the direction of `y`, storing the
1880    /// result in `x`.
1881    ///
1882    /// This operation is a generalization of the IEEE 754 *nextAfter*
1883    /// operation.
1884    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    /// Carries out the digitwise logical or of `lhs` and `rhs`, storing
1896    /// the result in `lhs`.
1897    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    /// Determines the ordering of `lhs` relative to `rhs`, using a partial
1905    /// order.
1906    ///
1907    /// If either `lhs` or `rhs` is a NaN, returns `None`. To force an ordering
1908    /// upon NaNs, use [`total_cmp`](Context::<Decimal<N>>::total_cmp).
1909    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    /// Adds `n` to zero, storing the result in `n`.
1937    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    /// Raises `x` to the power of `y`, storing the result in `x`.
1945    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    /// Takes product of elements in `iter`.
1953    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    /// Rounds or pads `lhs` so that it has the same exponent as `rhs`, storing
1964    /// the result in `lhs`.
1965    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    /// Reduces `n`'s coefficient to its shortest possible form without
1973    /// changing the value of the result, storing the result in `n`.
1974    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    /// Integer-divides `lhs` by `rhs`, storing the remainder in `lhs`.
1982    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    /// Like [`rem`](Context::<Decimal<N>>::rem), but uses the IEEE 754
1990    /// rules for remainder operations.
1991    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    /// Rescales `lhs` to have an exponent of `rhs`.
1999    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    /// Rounds the number to an integral value using the rounding mode in the
2007    /// context.
2008    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    /// Rounds `n` at a given "place from the left" in the number, akin to a
2016    /// shift right, round, and shift left.
2017    ///
2018    /// Note that this rounding will not drop integral digits (i.e those
2019    /// representing values at least 1), but can round off fractional values.
2020    ///
2021    /// `place` must be at least one and no greater than `N * 3`, i.e. a valid
2022    /// precision.
2023    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    /// Identical to [`round_to_place`] but simultaneously performs a [`reduce`]
2035    /// operation, as well.
2036    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    /// Shifts the digits of `lhs` by `rhs`, storing the result in `lhs`.
2048    ///
2049    /// If `rhs` is positive, shifts to the left. If `rhs` is negative, shifts
2050    /// to the right. Any digits "shifted in" will be zero.
2051    ///
2052    /// `rhs` specifies the number of positions to shift, and must be a finite
2053    /// integer.
2054    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    /// Rotates the digits of `lhs` by `rhs`, storing the result in `lhs`.
2062    ///
2063    /// If `rhs` is positive, rotates to the left. If `rhs` is negative, rotates
2064    /// to the right.
2065    ///
2066    /// `rhs` specifies the number of positions to rotate, and must be a finite
2067    /// integer.
2068    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    /// Multiplies `x` by 10<sup>`y`</sup>, storing the result in `x`.
2076    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    /// Computes the square root of `n`, storing the result in `n`.
2083    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    /// Subtracts `rhs` from `lhs`, storing the result in `lhs`.
2091    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    /// Sums all elements of `iter`.
2099    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    /// Determines the ordering of `lhs` relative to `rhs`, using the
2110    /// total order predicate defined in IEEE 754-2008.
2111    ///
2112    /// For a brief description of the ordering, consult [`f32::total_cmp`].
2113    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    /// Carries out the digitwise logical xor of `lhs` and `rhs`, storing
2139    /// the result in `lhs`.
2140    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    /// Returns `m` cast as a `Decimal::<N>`.
2148    ///
2149    /// `Context` uses similar statuses to arithmetic to express under- and
2150    /// overflow for values whose total precisions exceeds this context's.
2151    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}