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::{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    // TODO(benesch): check this at compile time, when that becomes possible.
46    if n < 12 || n > 999_999_999 {
47        panic!("Decimal<N>:: N is not in the range [12, 999999999]");
48    }
49}
50
51/// An arbitrary-precision decimal number.
52///
53/// The maximum number of digits that can be stored in the number is specified
54/// by `N * 3`. For example, a value of type `Decimal<3>` has space for nine
55/// decimal digits. This somewhat odd design is due to limitations of constant
56/// generic parameters in Rust. The intention is to someday make `N` correspond
57/// directly to the number of digits of precision.
58///
59/// `N` must be at least 12 and no greater than 999,999,999, though typically
60/// the stack size implies a smaller maximum for `N`. Due to limitations with
61/// constant generics it is not yet possible to enforce these restrictions at
62/// compile time, so they are checked at runtime.
63///
64/// For more details about e.g. the struct's fields, see the [upstream
65/// documentation](http://speleotrove.com/decimal/dnnumb.html).
66#[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    /// Must provide custom serde implementation for array defined with const
74    /// generic until something happens with
75    /// https://github.com/serde-rs/serde/issues/1272
76    #[cfg_attr(feature = "serde", serde(with = "lsu_serde"))]
77    pub(crate) lsu: [u16; N],
78}
79
80#[cfg(feature = "serde")]
81/// Provides a target for `serde(with = ...)` that permits deserializing `Decimal` values from
82/// primitive integers, `Strings`, or `str`.
83///
84/// ```rust
85/// use std::convert::TryFrom;
86/// use serde::{Deserialize, Serialize};
87/// const N: usize = 12;
88///
89/// #[repr(transparent)]
90/// #[derive(Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
91/// pub struct PrimitiveDeserializableDecimal<const N: usize>(
92///     #[serde(with = "dec::serde_decimal_from_non_float_primitives")] pub dec::Decimal<N>,
93/// );
94///
95/// let v: PrimitiveDeserializableDecimal<N> =
96///           serde_json::from_str("-1").expect("deserialization works");
97///
98/// assert_eq!(dec::Decimal::try_from(-1i32).unwrap(), v.0);
99/// ```
100///
101/// Note that the feature provided by this crate is only compatible with self-describing input
102/// formats, such as `JSON`, as it relies on [`Deserialize::deserialize_any`](deserialize_any).
103///
104/// [deserialize_any]:
105///     https://docs.rs/serde/latest/serde/trait.Deserializer.html#tymethod.deserialize_any
106pub 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    /// Serialize `d` using the default, derivsed `Serialize` implementation.
117    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    /// Deserializes the value permitting a conversion to a `Decimal<N>` from primitive integers
126    /// (`i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`), `String`, and `str`.
127    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    // Make this error checking shareable with manual deserialization impls.
323    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    /// Constructs a decimal number with `N / 3` digits of precision
346    /// representing the number 0.
347    pub fn zero() -> Decimal<N> {
348        Decimal::default()
349    }
350
351    /// Constructs a decimal number representing positive infinity.
352    pub fn infinity() -> Decimal<N> {
353        let mut d = Decimal::default();
354        d.bits = decnumber_sys::DECINF;
355        d
356    }
357
358    /// Constructs a decimal number representing a non-signaling NaN.
359    pub fn nan() -> Decimal<N> {
360        let mut d = Decimal::default();
361        d.bits = decnumber_sys::DECNAN;
362        d
363    }
364
365    // Constructs a decimal number equal to 2^32. We use this value internally
366    // to create decimals from primitive integers with more than 32 bits.
367    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    /// Computes the number of significant digits in the number.
375    ///
376    /// If the number is zero or infinite, returns 1. If the number is a NaN,
377    /// returns the number of digits in the payload.
378    pub fn digits(&self) -> u32 {
379        self.digits
380    }
381
382    /// Returns the individual digits of the coefficient in 8-bit, unpacked
383    /// [binary-coded decimal][bcd] format.
384    ///
385    /// [bcd]: https://en.wikipedia.org/wiki/Binary-coded_decimal
386    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    /// Returns the digits of the coefficient in [`decNumberUnit`][dnu] format,
395    /// which is a vector of `u16`, with element number representing
396    /// [`decnumber_sys::DECDPUN`] digits of the coefficient.
397    ///
398    /// The result is ordered with the least significant digits at index 0.
399    ///
400    /// [dpd]: http://speleotrove.com/decimal/dnnumb.html
401    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    /// Returns the value's coefficient as `T` or errors if not possible.
407    ///
408    /// All primitive ints are valid for `T`.
409    pub fn coefficient<T>(&mut self) -> Result<T, InvalidCoefficientError>
410    where
411        T: TryFrom<Decimal<N>>,
412    {
413        // Save current exponent to avoid an allocation.
414        let cur_exp = self.exponent();
415        // Temporarily set exponent to 0 to make convertible to primitive int
416        // `T`.
417        self.set_exponent(0);
418        let coefficient = <T>::try_from(*self);
419        // Revert the exponent to its previous value.
420        self.set_exponent(cur_exp);
421        match coefficient {
422            Ok(d) => Ok(d),
423            Err(_) => Err(InvalidCoefficientError),
424        }
425    }
426
427    /// Returns the number of elements required in the `lsu` to represent some
428    /// number of digits.
429    ///
430    /// This function is public and accepts a `u32` instead of a `Decimal` to
431    /// aid in recomposing ([`Self::from_raw_parts`]) values.
432    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    /// Computes the exponent of the number.
437    pub fn exponent(&self) -> i32 {
438        self.exponent
439    }
440
441    /// Sets `self`'s exponent to the provided value.
442    pub fn set_exponent(&mut self, exponent: i32) {
443        self.exponent = exponent;
444    }
445
446    /// Reports whether the number is finite.
447    ///
448    /// A finite number is one that is neither infinite nor a NaN.
449    pub fn is_finite(&self) -> bool {
450        (self.bits & decnumber_sys::DECSPECIAL) == 0
451    }
452
453    /// Reports whether the number is positive or negative infinity.
454    pub fn is_infinite(&self) -> bool {
455        (self.bits & decnumber_sys::DECINF) != 0
456    }
457
458    /// Reports whether the number is a NaN.
459    pub fn is_nan(&self) -> bool {
460        (self.bits & (decnumber_sys::DECNAN | decnumber_sys::DECSNAN)) != 0
461    }
462
463    /// Reports whether the number is negative.
464    ///
465    /// A negative number is either negative zero, less than zero, or NaN
466    /// with a sign of one. This corresponds to [`Decimal128::is_signed`], not
467    /// [`Decimal128::is_negative`].
468    pub fn is_negative(&self) -> bool {
469        (self.bits & decnumber_sys::DECNEG) != 0
470    }
471
472    /// Reports whether the number is a quiet NaN.
473    pub fn is_quiet_nan(&self) -> bool {
474        (self.bits & decnumber_sys::DECNAN) != 0
475    }
476
477    /// Reports whether the number is a signaling NaN.
478    pub fn is_signaling_nan(&self) -> bool {
479        (self.bits & decnumber_sys::DECSNAN) != 0
480    }
481
482    /// Reports whether the number has a special value.
483    ///
484    /// A special value is either infinity or NaN. This is the inverse of
485    /// [`Decimal::is_finite`].
486    pub fn is_special(&self) -> bool {
487        (self.bits & decnumber_sys::DECSPECIAL) != 0
488    }
489
490    /// Reports whether the number is positive or negative zero.
491    pub fn is_zero(&self) -> bool {
492        self.is_finite() && self.lsu[0] == 0 && self.digits == 1
493    }
494
495    /// Reports whether the quantum of the number matches the quantum of
496    /// `rhs`.
497    ///
498    /// Quantums are considered to match if the numbers have the same exponent,
499    /// are both NaNs, or both infinite.
500    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    /// Converts this decimal to a 32-bit decimal float.
518    ///
519    /// The result may be inexact. Use [`Context::<Decimal32>::from_decimal`]
520    /// to observe exceptional conditions.
521    pub fn to_decimal32(&self) -> Decimal32 {
522        Context::<Decimal32>::default().from_decimal(self)
523    }
524
525    /// Converts this decimal to a 64-bit decimal float.
526    ///
527    /// The result may be inexact. Use [`Context::<Decimal64>::from_decimal`]
528    /// to observe exceptional conditions.
529    pub fn to_decimal64(&self) -> Decimal64 {
530        Context::<Decimal64>::default().from_decimal(self)
531    }
532
533    /// Converts this decimal to a 128-bit decimal float.
534    ///
535    /// The result may be inexact. Use [`Context::<Decimal128>::from_decimal`]
536    /// to observe exceptional conditions.
537    pub fn to_decimal128(&self) -> Decimal128 {
538        Context::<Decimal128>::default().from_decimal(self)
539    }
540
541    /// Returns the raw parts of this decimal.
542    ///
543    /// The meaning of these parts are unspecified and subject to change. The
544    /// only guarantee is that these parts can be supplied as arguments to the
545    /// [`Decimal::from_raw_parts`] to produce a decimal equivalent to the
546    /// original.
547    pub fn to_raw_parts(&self) -> (u32, i32, u8, [u16; N]) {
548        (self.digits, self.exponent, self.bits, self.lsu)
549    }
550
551    /// Returns a `Decimal::<N>` with the supplied raw parts, which should be
552    /// generated using [`Decimal::to_raw_parts`].
553    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    /// Returns `self` as a [Packed Decimal][pd] number, including its scale
563    /// (i.e. its negated exponent) or `None` for special values.
564    ///
565    /// [pd]: http://speleotrove.com/decimal/dnpack.html
566    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            // Ensure space for sign nibble
573            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        // Null returned only for special values (already handled) or if `self`
587        // didn't fit within `bcd` (shouldn't happen).
588        assert!(!ret.is_null());
589        Some((bcd, scale))
590    }
591
592    /// Takes [Packed Decimal][pd] values and their scales (generated by
593    /// [`Self::to_packed_bcd`]) and returns a `Decimal`.
594    ///
595    /// # Errors
596    ///
597    /// - `bcd` contains more digits than the coefficient permits
598    /// - The adjusted exponent is out of range
599    /// - No sign nibble was found
600    /// - A sign nibble was found before the final nibble
601    ///
602    /// [pd]: http://speleotrove.com/decimal/dnpack.html
603    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    /// Returns a string of the number in standard notation, i.e. guaranteed to
622    /// not be scientific notation.
623    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        // We allocate space for all the digits plus a possible "-0." prefix.
638        // This is usually an overestimate but is an underestimate for very
639        // large or very small scales.
640        let mut out = String::with_capacity(digits.len() + 3);
641        if self.is_negative() {
642            out.push('-');
643        }
644
645        if e >= 0 {
646            // All digits before the decimal point.
647            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            // Digits span the decimal point.
657            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            // All digits after the decimal point.
667            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    /// Removes insignificant trailing zeros from a number, unconditionally, and
679    /// stores the modified value in `self`.
680    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    /// Note that this clones `self` to generate the negative value. For a
715    /// non-cloning method, use `Context::<N>::neg`.
716    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    /// Note that this clones `self` to generate the output. For a
730    /// non-cloning method, use `Context::<N>::add`.
731    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    /// Note that this clones `self` to generate the output. For a
748    /// non-cloning method, use `Context::<N>::div`.
749    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    /// Note that this clones `self` to generate the output. For a
766    /// non-cloning method, use `Context::<N>::mul`.
767    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    /// Note that this clones `self` to generate the output. For a
784    /// non-cloning method, use `Context::<N>::rem`.
785    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    /// Note that this clones `self` to generate the output. For a
802    /// non-cloning method, use `Context::<N>::sub`.
803    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        // String conversion may need up to `self.digits + 14` characters,
863        // per the libdecnumber documentation.
864        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
889/// Implements `std::convert::TryInto` semantics for `Decimal<N>` (represented
890/// by `$d`) into primitive integers (`$p`).
891macro_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        // inexact indicates you rounded away non-zero digits during rescale.
896        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        // try-catch
923        || -> 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
947/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
948/// this trait.
949impl<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
957/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
958/// this trait.
959impl<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
967/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
968/// this trait.
969impl<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
977/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
978/// this trait.
979impl<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
987/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
988/// this trait.
989impl<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
997/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
998/// this trait.
999impl<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
1007/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1008/// this trait.
1009impl<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
1017/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1018/// this trait.
1019impl<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
1027/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1028/// this trait.
1029impl<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
1037/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1038/// this trait.
1039impl<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
1047/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1048/// this trait.
1049impl<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
1057/// Refer to the comments on [`Context<Decimal<N>>::try_into_i32()`], which also apply to
1058/// this trait.
1059impl<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            // `powi` gives wrong results on some input, whereas `powf` does not
1087            f += <$p>::from(*u) * TEN.powf(e);
1088            e += DECDPUN_F;
1089        }
1090        if $d.is_negative() {
1091            f = -f;
1092        }
1093
1094        // Value over- or underflows $p:
1095        // - f.is_infinite() represents generic overflow
1096        // - f.is_nan() can occur when multiplying a coefficient unit by a power
1097        //   of 10 that exceeds the primitive type's maximum exponent
1098        // - (!$d.is_zero() && f == 0.0) represents underflow
1099        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
1198/// Generates a [`Decimal`] from an `i128` or fails if the result would be
1199/// imprecise, e.g. has more than `N*3` digits of precision.
1200///
1201/// For an infallible version of this function, see
1202/// [`Context<Decimal<N>>::from_i128`].
1203impl<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
1216/// Generates a [`Decimal`] from a `u128` or fails if the result would be
1217/// imprecise, e.g. has more than `N*3` digits of precision.
1218///
1219/// For an infallible version of this function, see
1220/// [`Context<Decimal<N>>::from_u128`].
1221impl<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        // TODO(benesch): this could be a static assertion or a where bound,
1310        // if either of those were supported.
1311        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    /// Returns the context's precision.
1322    ///
1323    /// Operations that use this context will be rounded to this length if
1324    /// necessary.
1325    pub fn precision(&self) -> usize {
1326        usize::try_from(self.inner.digits).expect("context digit count does not fit into usize")
1327    }
1328
1329    /// Sets the context's precision.
1330    ///
1331    /// The precision must be at least one and no greater than `N * 3`.
1332    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    /// Reports whether the context has exponent clamping enabled.
1341    ///
1342    /// See the `clamp` field in the documentation of libdecnumber's
1343    /// [decContext module] for details.
1344    ///
1345    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1346    pub fn clamp(&self) -> bool {
1347        self.inner.clamp != 0
1348    }
1349
1350    /// Sets whether the context has exponent clamping enabled.
1351    pub fn set_clamp(&mut self, clamp: bool) {
1352        self.inner.clamp = u8::from(clamp)
1353    }
1354
1355    /// Returns the context's maximum exponent.
1356    ///
1357    /// See the `emax` field in the documentation of libdecnumber's
1358    /// [decContext module] for details.
1359    ///
1360    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1361    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    /// Sets the context's maximum exponent.
1366    ///
1367    /// The maximum exponent must not be negative and no greater than
1368    /// 999,999,999.
1369    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    /// Returns the context's minimum exponent.
1378    ///
1379    /// See the `emin` field in the documentation of libdecnumber's
1380    /// [decContext module] for details.
1381    ///
1382    /// [decContext module]: http://speleotrove.com/decimal/dncont.html
1383    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    /// Sets the context's minimum exponent.
1388    ///
1389    /// The minimum exponent must not be positive and no smaller than
1390    /// -999,999,999.
1391    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    /// Parses a number from its string representation.
1400    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    /// Parses a number from its string representation.
1409    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    /// Classifies the number.
1427    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    /// Computes the absolute value of `n`, storing the result in `n`.
1432    ///
1433    /// This has the same effect as [`Context::<Decimal<N>>::plus`] unless
1434    /// `n` is negative, in which case it has the same effect as
1435    /// [`Context::<Decimal<N>>::minus`].
1436    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    /// Adds `lhs` and `rhs`, storing the result in `lhs`.
1444    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    /// Carries out the digitwise logical and of `lhs` and `rhs`, storing
1452    /// the result in `lhs`.
1453    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    /// Divides `lhs` by `rhs`, storing the result in `lhs`.
1461    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    /// Divides `lhs` by `rhs`, storing the integer part of the result in `lhs`.
1469    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    /// Raises *e* to the power of `n`, storing the result in `n`.
1477    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    /// Calculates the fused multiply-add `(x * y) + z` and stores the result
1485    /// in `x`.
1486    ///
1487    /// The multiplication is carried out first and is exact, so this operation
1488    /// only has the one, final rounding.
1489    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    /// Constructs a number from an `i32`.
1502    pub fn from_i32(&mut self, n: i32) -> Decimal<N> {
1503        Decimal::<N>::from(n)
1504    }
1505
1506    /// Constructs a number from an `i32`.
1507    pub fn from_u32(&mut self, n: u32) -> Decimal<N> {
1508        Decimal::<N>::from(n)
1509    }
1510
1511    /// Constructs a number from an `i64`.
1512    pub fn from_i64(&mut self, n: i64) -> Decimal<N> {
1513        decimal_from_signed_int!(self, n)
1514    }
1515
1516    /// Constructs a number from a `u64`.
1517    pub fn from_u64(&mut self, n: u64) -> Decimal<N> {
1518        decimal_from_unsigned_int!(self, n)
1519    }
1520
1521    /// Constructs a number from an `i128`.
1522    ///
1523    /// Note that this function can return inexact results for numbers with more
1524    /// than `N` * 3 places of precision, e.g. where `N` is 12,
1525    /// `9_999_999_999_999_999_999_999_999_999_999_999_999i128`,
1526    /// `-9_999_999_999_999_999_999_999_999_999_999_999_999i128`, `i128::MAX`,
1527    /// `i128::MIN`, etc.
1528    ///
1529    /// However, some numbers more than `N` * 3 places of precision retain their
1530    /// exactness, e.g. `1_000_000_000_000_000_000_000_000_000_000_000_000i128`.
1531    ///
1532    /// ```
1533    /// const N: usize = 12;
1534    /// use dec::Decimal;
1535    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1536    /// let d = ctx.from_i128(i128::MAX);
1537    /// // Inexact result
1538    /// assert!(ctx.status().inexact());
1539    ///
1540    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1541    /// let d = ctx.from_i128(1_000_000_000_000_000_000_000_000_000_000_000_000i128);
1542    /// // Exact result
1543    /// assert!(!ctx.status().inexact());
1544    /// ```
1545    ///
1546    /// To avoid inexact results when converting from large `i64`, use
1547    /// [`crate::Decimal128`] instead.
1548    pub fn from_i128(&mut self, n: i128) -> Decimal<N> {
1549        decimal_from_signed_int!(self, n)
1550    }
1551
1552    /// Constructs a number from an `u128`.
1553    ///
1554    /// Note that this function can return inexact results for numbers with more
1555    /// than `N` * 3 places of precision, e.g. where `N` is 12,
1556    /// `10_000_000_000_000_000_000_000_000_000_000_001u128` and `u128::MAX`.
1557    ///
1558    /// However, some numbers more than `N` * 3 places of precision retain their
1559    /// exactness,  e.g. `10_000_000_000_000_000_000_000_000_000_000_000u128`.
1560    ///
1561    /// ```
1562    /// const N: usize = 12;
1563    /// use dec::Decimal;
1564    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1565    /// let d = ctx.from_u128(u128::MAX);
1566    /// // Inexact result
1567    /// assert!(ctx.status().inexact());
1568    ///
1569    /// let mut ctx = dec::Context::<Decimal::<N>>::default();
1570    /// let d = ctx.from_u128(1_000_000_000_000_000_000_000_000_000_000_000_000u128);
1571    /// // Exact result
1572    /// assert!(!ctx.status().inexact());
1573    /// ```
1574    pub fn from_u128(&mut self, n: u128) -> Decimal<N> {
1575        decimal_from_unsigned_int!(self, n)
1576    }
1577
1578    /// Attempts to convert `d` to `u8` or fails if not possible.
1579    ///
1580    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1581    /// function.
1582    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    /// Attempts to convert `d` to `i8` or fails if not possible.
1588    ///
1589    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1590    /// function.
1591    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    /// Attempts to convert `d` to `u16` or fails if not possible.
1597    ///
1598    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1599    /// function.
1600    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    /// Attempts to convert `d` to `i16` or fails if not possible.
1606    ///
1607    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1608    /// function.
1609    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    /// Attempts to convert `d` to `i32` or fails if not possible. Note that
1615    /// when returning an error, `self`'s [`context::Status`] is set to
1616    /// `invalid_operation` in addition to using Rust's `Err` return value.
1617    ///
1618    /// Note that this function:
1619    /// - Accepts any value that can be rescaled to an exponent of 0 without
1620    ///   becoming inexact. For example, `123.000` and `123E2` are valid
1621    ///   `Decimal` values.
1622    ///
1623    ///   The corollary is that values that cannot be rescaled to an exponent of
1624    ///   0 error.
1625    /// - Errors if `self.status()` is set to `invalid_operation` irrespective
1626    ///   of whether or not this specific invocation of the function set that
1627    ///   status.
1628    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        // inexact indicates you rounded away non-zero digits during rescale.
1632        if self.status().invalid_operation() || self.status().inexact() {
1633            Err(TryFromDecimalError)
1634        } else {
1635            Ok(i)
1636        }
1637    }
1638
1639    /// Attempts to convert `d` to `u32` or fails if not possible.
1640    ///
1641    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1642    /// function.
1643    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        // inexact indicates you rounded away non-zero digits during rescale.
1647        if self.status().invalid_operation() || self.status().inexact() {
1648            Err(TryFromDecimalError)
1649        } else {
1650            Ok(i)
1651        }
1652    }
1653
1654    /// Attempts to convert `d` to `isize` or fails if not possible.
1655    ///
1656    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1657    /// function.
1658    #[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    /// Attempts to convert `d` to `isize` or fails if not possible.
1665    ///
1666    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1667    /// function.
1668    #[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    /// Attempts to convert `d` to `i64` or fails if not possible.
1675    ///
1676    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1677    /// function.
1678    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    /// Attempts to convert `d` to `i128` or fails if not possible.
1683    ///
1684    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1685    /// function.
1686    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    /// Attempts to convert `d` to `usize` or fails if not possible.
1691    ///
1692    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1693    /// function.
1694    #[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    /// Attempts to convert `d` to `usize` or fails if not possible.
1701    ///
1702    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1703    /// function.
1704    #[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    /// Attempts to convert `d` to `u64` or fails if not possible.
1711    ///
1712    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1713    /// function.
1714    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    /// Attempts to convert `d` to `u128` or fails if not possible.
1719    ///
1720    /// Refer to the comments on [`Self::try_into_i32()`], which also apply to this
1721    /// function.
1722    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    /// Attempts to convert `d` to `f32` or fails if not possible.
1727    ///
1728    /// Note that this function:
1729    /// - Errors for values that over- or underflow `f32`, rather than returning
1730    ///   infinity or `0.0`, respectively.
1731    /// - Returns a primitive infinity or NaN if `d` is an equivalent value.
1732    pub fn try_into_f32(&mut self, d: Decimal<N>) -> Result<f32, TryFromDecimalError> {
1733        decnum_tryinto_primitive_float!(f32, self, d)
1734    }
1735
1736    /// Attempts to convert `d` to `f32` or fails if not possible.
1737    ///
1738    /// Refer to the comments on [`Self::try_into_f32()`], which also apply to this
1739    /// function.
1740    pub fn try_into_f64(&mut self, d: Decimal<N>) -> Result<f64, TryFromDecimalError> {
1741        decnum_tryinto_primitive_float!(f64, self, d)
1742    }
1743
1744    /// Converts an `f32` to a `Decimal<N>`.
1745    ///
1746    /// Note that this conversion is infallible because `f32`'s:
1747    /// - Maximum precision is ~8
1748    /// - Min/max exponent is ~ -37, 37
1749    ///
1750    /// Both of these are guaranteed to fit comfortably within `Decimal`'s
1751    /// constraints.
1752    pub fn from_f32(&mut self, n: f32) -> Decimal<N> {
1753        self.from_float(n)
1754    }
1755
1756    /// Converts an `f64` to a `Decimal<N>`.
1757    ///
1758    /// Note that this conversion is infallible because `f64`'s:
1759    /// - Maximum precision is ~18
1760    /// - Min/max exponent is ~ -305, 305
1761    ///
1762    /// Both of these are guaranteed to fit comfortably within `Decimal`'s
1763    /// constraints.
1764    pub fn from_f64(&mut self, n: f64) -> Decimal<N> {
1765        self.from_float(n)
1766    }
1767
1768    /// Converts a `f32` or a `f64` value to a `Decimal<N>`.
1769    ///
1770    /// Note that this conversion is infallible because `f64`'s:
1771    /// - Maximum precision is ~18
1772    /// - Min/max exponent is ~ -305, 305
1773    ///
1774    /// Both of these are guaranteed to fit comfortably within `Decimal`'s
1775    /// constraints.
1776    // NOTE: The code is generic over any T: LowerExp but passing something like f128 wouldn't
1777    // always work since there are f128 values that don't fit in 24 bytes.
1778    pub fn from_float<T: LowerExp + Display>(&mut self, n: T) -> Decimal<N> {
1779        // The maximum bytes needed to store the decimal representation of a f64.
1780        // We follow stdlib's buffer size of 1024 bytes.
1781        // See: https://github.com/rust-lang/rust/blob/1.86.0/library/core/src/fmt/float.rs#L37
1782        const MAX_LEN: usize = 1024;
1783
1784        // Create a buffer that can hold the longest float plus a nul character for the C string
1785        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        // SAFETY:
1790        //  * buf was zero-initialized
1791        //  * Exactly MAX_LEN - unwritten.len() bytes have been modified
1792        //  * Formatting a float never writes nul characters
1793        //  Therefore the produced slice contains exactly one nul character
1794        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    /// Computes the digitwise logical inversion of `n`, storing the result in
1800    /// `n`.
1801    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    /// Computes the natural logarithm of `n`, storing the result in `n`.
1809    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    /// Computes the base-10 logarithm of `n`, storing the result in `n`.
1817    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    /// Computes the adjusted exponent of the number, according to IEEE 754
1825    /// rules.
1826    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    /// Places whichever of `lhs` and `rhs` is larger in `lhs`.
1834    ///
1835    /// The comparison is performed using the same rules as for
1836    /// [`total_cmp`](Context::<Decimal128>::total_cmp).
1837    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    /// Places whichever of `lhs` and `rhs` has the larger absolute value in
1845    /// `lhs`.
1846    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    /// Places whichever of `lhs` and `rhs` is smaller in `lhs`.
1854    ///
1855    /// The comparison is performed using the same rules as for
1856    /// [`total_cmp`](Context::<Decimal128>::total_cmp).
1857    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    /// Places whichever of `lhs` and `rhs` has the smaller absolute value in
1865    /// `lhs`.
1866    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    /// Subtracts `n` from zero, storing the result in `n`.
1874    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    /// Multiples `lhs` by `rhs`, storing the result in `lhs`.
1881    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    /// Negates the sign of `n`, storing the result in `n`. Note that unlike
1889    /// `minus`, no exception or error can occur.
1890    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    /// Computes the next number to `n` in the direction of negative infinity,
1897    /// storing the result in `n`.
1898    ///
1899    /// This operation is a generalization of the IEEE 754 *nextDown* operation.
1900    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    /// Computes the next number to `n` in the direction of positive infinity,
1907    /// storing the result in `n`.
1908    ///
1909    /// This operation is a generalization of the IEEE 754 *nextUp* operation.
1910    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    /// Computes the next number to `x` in the direction of `y`, storing the
1917    /// result in `x`.
1918    ///
1919    /// This operation is a generalization of the IEEE 754 *nextAfter*
1920    /// operation.
1921    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    /// Carries out the digitwise logical or of `lhs` and `rhs`, storing
1933    /// the result in `lhs`.
1934    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    /// Determines the ordering of `lhs` relative to `rhs`, using a partial
1942    /// order.
1943    ///
1944    /// If either `lhs` or `rhs` is a NaN, returns `None`. To force an ordering
1945    /// upon NaNs, use [`total_cmp`](Context::<Decimal<N>>::total_cmp).
1946    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    /// Adds `n` to zero, storing the result in `n`.
1974    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    /// Raises `x` to the power of `y`, storing the result in `x`.
1982    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    /// Takes product of elements in `iter`.
1990    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    /// Rounds or pads `lhs` so that it has the same exponent as `rhs`, storing
2001    /// the result in `lhs`.
2002    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    /// Reduces `n`'s coefficient to its shortest possible form without
2010    /// changing the value of the result, storing the result in `n`.
2011    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    /// Integer-divides `lhs` by `rhs`, storing the remainder in `lhs`.
2019    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    /// Like [`rem`](Context::<Decimal<N>>::rem), but uses the IEEE 754
2027    /// rules for remainder operations.
2028    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    /// Rescales `lhs` to have an exponent of `rhs`.
2036    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    /// Rounds the number to an integral value using the rounding mode in the
2044    /// context.
2045    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    /// Rounds `n` at a given "place from the left" in the number, akin to a
2053    /// shift right, round, and shift left.
2054    ///
2055    /// Note that this rounding will not drop integral digits (i.e those
2056    /// representing values at least 1), but can round off fractional values.
2057    ///
2058    /// `place` must be at least one and no greater than `N * 3`, i.e. a valid
2059    /// precision.
2060    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    /// Identical to [`round_to_place`] but simultaneously performs a [`reduce`]
2072    /// operation, as well.
2073    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    /// Shifts the digits of `lhs` by `rhs`, storing the result in `lhs`.
2085    ///
2086    /// If `rhs` is positive, shifts to the left. If `rhs` is negative, shifts
2087    /// to the right. Any digits "shifted in" will be zero.
2088    ///
2089    /// `rhs` specifies the number of positions to shift, and must be a finite
2090    /// integer.
2091    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    /// Rotates the digits of `lhs` by `rhs`, storing the result in `lhs`.
2099    ///
2100    /// If `rhs` is positive, rotates to the left. If `rhs` is negative, rotates
2101    /// to the right.
2102    ///
2103    /// `rhs` specifies the number of positions to rotate, and must be a finite
2104    /// integer.
2105    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    /// Multiplies `x` by 10<sup>`y`</sup>, storing the result in `x`.
2113    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    /// Computes the square root of `n`, storing the result in `n`.
2120    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    /// Subtracts `rhs` from `lhs`, storing the result in `lhs`.
2128    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    /// Sums all elements of `iter`.
2136    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    /// Determines the ordering of `lhs` relative to `rhs`, using the
2147    /// total order predicate defined in IEEE 754-2008.
2148    ///
2149    /// For a brief description of the ordering, consult [`f32::total_cmp`].
2150    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    /// Carries out the digitwise logical xor of `lhs` and `rhs`, storing
2176    /// the result in `lhs`.
2177    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    /// Returns `m` cast as a `Decimal::<N>`.
2185    ///
2186    /// `Context` uses similar statuses to arithmetic to express under- and
2187    /// overflow for values whose total precisions exceeds this context's.
2188    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}