dec/
decimal128.rs

1// Copyright Materialize, Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.inner (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.inner
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;
18use std::convert::TryInto;
19use std::ffi::{CStr, CString};
20use std::fmt;
21use std::iter::{Product, Sum};
22use std::marker::PhantomData;
23use std::mem::MaybeUninit;
24use std::ops::{
25    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
26};
27use std::str::FromStr;
28
29use libc::c_char;
30#[cfg(feature = "num-traits")]
31use num_traits::{MulAdd, MulAddAssign, One, Zero};
32
33use crate::context::{Class, Context};
34use crate::decimal::Decimal;
35use crate::decimal32::Decimal32;
36use crate::decimal64::Decimal64;
37use crate::error::ParseDecimalError;
38
39/// A 128-bit decimal floating-point number.
40///
41/// Additional operations are defined as methods on the [`Context`] type.
42///
43/// For convenience, `Decimal128` overloads many of the standard Rust operators.
44/// For example, you can use the standard `+` operator to add two values
45/// together:
46///
47/// ```
48/// use dec::Decimal128;
49/// let a = Decimal128::from(1);
50/// let b = Decimal128::from(2);
51/// assert_eq!(a + b, Decimal128::from(3));
52/// ```
53///
54/// These overloaded operators implicitly construct a single-use default
55/// context, which has some performance overhead. For maximum performance when
56/// performing operations in bulk, use a long-lived context that you construct
57/// yourself.
58#[repr(transparent)]
59#[derive(Clone, Copy)]
60pub struct Decimal128 {
61    pub(crate) inner: decnumber_sys::decQuad,
62}
63
64impl Decimal128 {
65    /// The value that represents Not-a-Number (NaN).
66    pub const NAN: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
67        [
68            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c,
69        ]
70    } else {
71        [
72            0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
73        ]
74    });
75
76    /// The value that represents zero.
77    pub const ZERO: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
78        [
79            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
80        ]
81    } else {
82        [
83            0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
84        ]
85    });
86
87    /// The value that represents one.
88    pub const ONE: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
89        [
90            0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
91        ]
92    } else {
93        [
94            0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
95        ]
96    });
97
98    /// The value that represents 2<sup>32</sup>.
99    const TWO_POW_32: Decimal128 = Decimal128::from_ne_bytes(if cfg!(target_endian = "little") {
100        [
101            0x7A, 0xB5, 0xAF, 0x15, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x08, 0x22,
102        ]
103    } else {
104        [
105            0x22, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x15, 0xAF, 0xB5, 0x7A,
106        ]
107    });
108
109    /// Creates a number from its representation as a little-endian byte array.
110    pub fn from_le_bytes(mut bytes: [u8; 16]) -> Decimal128 {
111        if cfg!(target_endian = "big") {
112            bytes.reverse();
113        }
114        Decimal128::from_ne_bytes(bytes)
115    }
116
117    /// Creates a number from its representation as a big-endian byte array.
118    pub fn from_be_bytes(mut bytes: [u8; 16]) -> Decimal128 {
119        if cfg!(target_endian = "little") {
120            bytes.reverse();
121        }
122        Decimal128::from_ne_bytes(bytes)
123    }
124
125    /// Creates a number from its representation as a byte array in the
126    /// native endianness of the target platform.
127    pub const fn from_ne_bytes(bytes: [u8; 16]) -> Decimal128 {
128        Decimal128 {
129            inner: decnumber_sys::decQuad { bytes },
130        }
131    }
132
133    /// Returns the memory representation of the number as a byte array in
134    /// little-endian order.
135    pub fn to_le_bytes(&self) -> [u8; 16] {
136        let mut bytes = self.to_ne_bytes();
137        if cfg!(target_endian = "big") {
138            bytes.reverse();
139        }
140        bytes
141    }
142
143    /// Returns the memory representation of the number as a byte array in
144    /// big-endian order.
145    pub fn to_be_bytes(&self) -> [u8; 16] {
146        let mut bytes = self.to_ne_bytes();
147        if cfg!(target_endian = "little") {
148            bytes.reverse();
149        }
150        bytes
151    }
152
153    /// Returns the memory representation of the number as a byte array in
154    /// the native endianness of the target platform.
155    pub fn to_ne_bytes(&self) -> [u8; 16] {
156        self.inner.bytes
157    }
158
159    /// Classifies the number.
160    pub fn class(&self) -> Class {
161        Class::from_c(unsafe { decnumber_sys::decQuadClass(&self.inner) })
162    }
163
164    /// Computes the number of significant digits in the number.
165    ///
166    /// If the number is zero or infinite, returns 1. If the number is a NaN,
167    /// returns the number of digits in the payload.
168    pub fn digits(&self) -> u32 {
169        unsafe { decnumber_sys::decQuadDigits(&self.inner) }
170    }
171
172    /// Computes the coefficient of the number.
173    ///
174    /// If the number is a special value (i.e., NaN or infinity), returns zero.
175    pub fn coefficient(&self) -> i128 {
176        let mut dpd = if cfg!(target_endian = "big") {
177            u128::from_be_bytes(self.inner.bytes)
178        } else {
179            u128::from_le_bytes(self.inner.bytes)
180        };
181
182        // Densely packed decimals are 10-bit strings.
183        let dpd_mask = 0b11_1111_1111;
184
185        let mut dpd2bin = |include_mill: bool| -> i128 {
186            let mut r: i128 = 0;
187
188            // Lossy conversion from u128 to usize is fine because we only care
189            // about the 10 rightmost bits.
190            r += i128::from(unsafe { decnumber_sys::DPD2BIN[dpd as usize & dpd_mask] });
191            dpd >>= 10;
192            r += i128::from(unsafe { decnumber_sys::DPD2BINK[dpd as usize & dpd_mask] });
193            dpd >>= 10;
194            if include_mill {
195                r += i128::from(unsafe { decnumber_sys::DPD2BINM[dpd as usize & dpd_mask] });
196                dpd >>= 10;
197            }
198
199            r
200        };
201
202        // Digits 26-34
203        let mut r = dpd2bin(true);
204        // Digits 17-25
205        r += dpd2bin(true) * 1_000_000_000;
206        // Digits 8-16
207        r += dpd2bin(true) * 1_000_000_000_000_000_000;
208        // Digits 2-7
209        r += dpd2bin(false) * 1_000_000_000_000_000_000_000_000_000;
210
211        // Digit 1
212        let h = i128::from(unsafe { decnumber_sys::DECCOMBMSD[(dpd >> 12) as usize] });
213
214        if h > 0 {
215            r += h * 1_000_000_000_000_000_000_000_000_000_000_000;
216        }
217
218        if self.is_negative() {
219            r *= -1;
220        }
221
222        r
223    }
224
225    /// Returns the individual digits of the coefficient in 8-bit, unpacked
226    /// [binary-coded decimal][bcd] format.
227    ///
228    /// [bcd]: https://en.wikipedia.org/wiki/Binary-coded_decimal
229    pub fn coefficient_digits(&self) -> [u8; decnumber_sys::DECQUAD_Pmax] {
230        let mut buf = [0u8; decnumber_sys::DECQUAD_Pmax];
231        unsafe {
232            decnumber_sys::decQuadGetCoefficient(&self.inner, buf.as_mut_ptr() as *mut u8);
233        }
234        buf
235    }
236
237    /// Computes the exponent of the number.
238    pub fn exponent(&self) -> i32 {
239        unsafe { decnumber_sys::decQuadGetExponent(&self.inner) }
240    }
241
242    /// Returns an equivalent number whose encoding is guaranteed to be
243    /// canonical.
244    pub fn canonical(mut self) -> Decimal128 {
245        let inner = &mut self.inner as *mut decnumber_sys::decQuad;
246        unsafe {
247            decnumber_sys::decQuadCanonical(inner, inner);
248        }
249        self
250    }
251
252    /// Reports whether the encoding of the number is canonical.
253    pub fn is_canonical(&self) -> bool {
254        unsafe { decnumber_sys::decQuadIsCanonical(&self.inner) != 0 }
255    }
256
257    /// Reports whether the number is finite.
258    ///
259    /// A finite number is one that is neither infinite nor a NaN.
260    pub fn is_finite(&self) -> bool {
261        unsafe { decnumber_sys::decQuadIsFinite(&self.inner) != 0 }
262    }
263
264    /// Reports whether the number is positive or negative infinity.
265    pub fn is_infinite(&self) -> bool {
266        unsafe { decnumber_sys::decQuadIsInfinite(&self.inner) != 0 }
267    }
268
269    /// Reports whether the number is an integer.
270    ///
271    /// An integer is a decimal number that is finite and has an exponent of
272    /// zero.
273    pub fn is_integer(&self) -> bool {
274        unsafe { decnumber_sys::decQuadIsInteger(&self.inner) != 0 }
275    }
276
277    /// Reports whether the number is a valid argument for logical operations.
278    ///
279    /// A number is a valid argument for logical operations if it is a
280    /// nonnegative integer where each digit is either zero or one.
281    pub fn is_logical(&self) -> bool {
282        unsafe { decnumber_sys::decQuadIsInteger(&self.inner) != 0 }
283    }
284
285    /// Reports whether the number is a NaN.
286    pub fn is_nan(&self) -> bool {
287        unsafe { decnumber_sys::decQuadIsNaN(&self.inner) != 0 }
288    }
289
290    /// Reports whether the number is less than zero and not a NaN.
291    pub fn is_negative(&self) -> bool {
292        unsafe { decnumber_sys::decQuadIsNegative(&self.inner) != 0 }
293    }
294
295    /// Reports whether the number is normal.
296    ///
297    /// A normal number is finite, non-zero, and not subnormal.
298    pub fn is_normal(&self) -> bool {
299        unsafe { decnumber_sys::decQuadIsNormal(&self.inner) != 0 }
300    }
301
302    /// Reports whether the number is greater than zero and not a NaN.
303    pub fn is_positive(&self) -> bool {
304        unsafe { decnumber_sys::decQuadIsPositive(&self.inner) != 0 }
305    }
306
307    /// Reports whether the number is a signaling NaN.
308    pub fn is_signaling_nan(&self) -> bool {
309        unsafe { decnumber_sys::decQuadIsSignaling(&self.inner) != 0 }
310    }
311
312    /// Reports whether the number has a sign of 1.
313    ///
314    /// Note that zeros and NaNs may have a sign of 1.
315    pub fn is_signed(&self) -> bool {
316        unsafe { decnumber_sys::decQuadIsSigned(&self.inner) != 0 }
317    }
318
319    /// Reports whether the number is subnormal.
320    ///
321    /// A subnormal number is finite, non-zero, and has magnitude less than
322    /// 10<sup>emin</sup>.
323    pub fn is_subnormal(&self) -> bool {
324        unsafe { decnumber_sys::decQuadIsSubnormal(&self.inner) != 0 }
325    }
326
327    /// Reports whether the number is positive or negative zero.
328    pub fn is_zero(&self) -> bool {
329        unsafe { decnumber_sys::decQuadIsZero(&self.inner) != 0 }
330    }
331
332    /// Reports whether the quantum of the number matches the quantum of
333    /// `rhs`.
334    ///
335    /// Quantums are considered to match if the numbers have the same exponent,
336    /// are both NaNs, or both infinite.
337    pub fn quantum_matches(&self, rhs: &Decimal128) -> bool {
338        unsafe { decnumber_sys::decQuadSameQuantum(&self.inner, &rhs.inner) != 0 }
339    }
340
341    /// Determines the ordering of this number relative to `rhs`, using the
342    /// total order predicate defined in IEEE 754-2008.
343    ///
344    /// For a brief description of the ordering, consult [`f32::total_cmp`].
345    pub fn total_cmp(&self, rhs: &Decimal128) -> Ordering {
346        let mut d = Decimal128::ZERO;
347        unsafe {
348            decnumber_sys::decQuadCompareTotal(&mut d.inner, &self.inner, &rhs.inner);
349        }
350        if d.is_positive() {
351            Ordering::Greater
352        } else if d.is_negative() {
353            Ordering::Less
354        } else {
355            debug_assert!(d.is_zero());
356            Ordering::Equal
357        }
358    }
359
360    /// Returns a string of the number in standard notation, i.e. guaranteed to
361    /// not be scientific notation.
362    pub fn to_standard_notation_string(&self) -> String {
363        if !self.is_finite() {
364            return self.to_string();
365        }
366        let mut digits = [b'0'; decnumber_sys::DECQUAD_Pmax];
367        let mut digits_idx = 0;
368        let (sourlo, sourml, sourmh, sourhi) = if cfg!(target_endian = "little") {
369            (
370                u32::from_ne_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
371                u32::from_ne_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
372                u32::from_ne_bytes(self.inner.bytes[8..12].try_into().unwrap()) as usize,
373                u32::from_ne_bytes(self.inner.bytes[12..16].try_into().unwrap()) as usize,
374            )
375        } else {
376            (
377                u32::from_ne_bytes(self.inner.bytes[12..16].try_into().unwrap()) as usize,
378                u32::from_ne_bytes(self.inner.bytes[8..12].try_into().unwrap()) as usize,
379                u32::from_ne_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
380                u32::from_ne_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
381            )
382        };
383
384        let comb = ((sourhi >> 26) & 0x1f) as usize;
385        let msd = unsafe { decnumber_sys::DECCOMBMSD[comb] };
386
387        if msd > 0 {
388            digits[digits_idx] = b'0' + msd as u8;
389            digits_idx += 1;
390        }
391
392        #[allow(unused_assignments)]
393        let mut dpd: usize = 0;
394
395        dpd = (sourhi >> 4) & 0x3ff; // declet 1
396        dpd2char!(dpd, digits, digits_idx);
397
398        dpd = ((sourhi & 0xf) << 6) | (sourmh >> 26); // declet 2
399        dpd2char!(dpd, digits, digits_idx);
400
401        dpd = (sourmh >> 16) & 0x3ff; // declet 3
402        dpd2char!(dpd, digits, digits_idx);
403
404        dpd = (sourmh >> 6) & 0x3ff; // declet 4
405        dpd2char!(dpd, digits, digits_idx);
406
407        dpd = ((sourmh & 0x3f) << 4) | (sourml >> 28); // declet 5
408        dpd2char!(dpd, digits, digits_idx);
409
410        dpd = (sourml >> 18) & 0x3ff; // declet 6
411        dpd2char!(dpd, digits, digits_idx);
412
413        dpd = (sourml >> 8) & 0x3ff; // declet 7
414        dpd2char!(dpd, digits, digits_idx);
415
416        dpd = ((sourml & 0xff) << 2) | (sourlo >> 30); // declet 8
417        dpd2char!(dpd, digits, digits_idx);
418
419        dpd = (sourlo >> 20) & 0x3ff; // declet 9
420        dpd2char!(dpd, digits, digits_idx);
421
422        dpd = (sourlo >> 10) & 0x3ff; // declet 10
423        dpd2char!(dpd, digits, digits_idx);
424
425        dpd = (sourlo) & 0x3ff; // declet 11
426        dpd2char!(dpd, digits, digits_idx);
427
428        stringify_digits!(self, digits, digits_idx)
429    }
430}
431
432impl Default for Decimal128 {
433    fn default() -> Decimal128 {
434        Decimal128::ZERO
435    }
436}
437
438impl fmt::Debug for Decimal128 {
439    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440        fmt::Display::fmt(self, f)
441    }
442}
443
444impl fmt::Display for Decimal128 {
445    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446        let mut buf = ['\0'; decnumber_sys::DECQUAD_String];
447        let c_str = unsafe {
448            if f.alternate() {
449                decnumber_sys::decQuadToEngString(&self.inner, buf.as_mut_ptr() as *mut c_char);
450            } else {
451                decnumber_sys::decQuadToString(&self.inner, buf.as_mut_ptr() as *mut c_char);
452            }
453            CStr::from_ptr(buf.as_ptr() as *const c_char)
454        };
455        f.write_str(c_str.to_str().expect("decQuadToString yields valid UTF-8"))
456    }
457}
458
459impl FromStr for Decimal128 {
460    type Err = ParseDecimalError;
461
462    fn from_str(s: &str) -> Result<Decimal128, ParseDecimalError> {
463        Context::<Decimal128>::default().parse(s)
464    }
465}
466
467impl From<i32> for Decimal128 {
468    fn from(n: i32) -> Decimal128 {
469        let mut d = Decimal128::ZERO;
470        unsafe {
471            decnumber_sys::decQuadFromInt32(&mut d.inner, n);
472        }
473        d
474    }
475}
476
477impl From<u32> for Decimal128 {
478    fn from(n: u32) -> Decimal128 {
479        let mut d = Decimal128::ZERO;
480        unsafe {
481            decnumber_sys::decQuadFromUInt32(&mut d.inner, n);
482        }
483        d
484    }
485}
486
487// NOTE(benesch): Looking at the implementation of decFloatFromInt32, I suspect
488// there is something much more clever we could do to convert from i64/u64 that
489// uses the BIN2DPD tables directly.
490
491impl From<i64> for Decimal128 {
492    fn from(n: i64) -> Decimal128 {
493        let mut cx = Context::<Decimal128>::default();
494        let d = from_signed_int!(Decimal128, cx, n);
495        debug_assert!(!cx.status().any());
496        d
497    }
498}
499
500impl From<u64> for Decimal128 {
501    fn from(n: u64) -> Decimal128 {
502        let mut cx = Context::<Decimal128>::default();
503        let d = from_unsigned_int!(Decimal128, cx, n);
504        debug_assert!(!cx.status().any());
505        d
506    }
507}
508
509impl From<Decimal32> for Decimal128 {
510    fn from(d32: Decimal32) -> Decimal128 {
511        Decimal128::from(Decimal64::from(d32))
512    }
513}
514
515impl From<Decimal64> for Decimal128 {
516    fn from(d64: Decimal64) -> Decimal128 {
517        let mut d128 = Decimal128::ZERO;
518        unsafe {
519            decnumber_sys::decDoubleToWider(&d64.inner, &mut d128.inner);
520        }
521        d128
522    }
523}
524
525impl PartialOrd for Decimal128 {
526    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
527        Context::<Decimal128>::default().partial_cmp(*self, *other)
528    }
529}
530
531impl PartialEq for Decimal128 {
532    fn eq(&self, other: &Self) -> bool {
533        self.partial_cmp(other) == Some(Ordering::Equal)
534    }
535}
536
537impl Neg for Decimal128 {
538    type Output = Decimal128;
539
540    fn neg(self) -> Decimal128 {
541        Context::<Decimal128>::default().minus(self)
542    }
543}
544
545impl Add<Decimal128> for Decimal128 {
546    type Output = Decimal128;
547
548    fn add(self, rhs: Decimal128) -> Decimal128 {
549        Context::<Decimal128>::default().add(self, rhs)
550    }
551}
552
553impl AddAssign<Decimal128> for Decimal128 {
554    fn add_assign(&mut self, rhs: Decimal128) {
555        *self = Context::<Decimal128>::default().add(*self, rhs);
556    }
557}
558
559impl Div<Decimal128> for Decimal128 {
560    type Output = Decimal128;
561
562    fn div(self, rhs: Decimal128) -> Decimal128 {
563        Context::<Decimal128>::default().div(self, rhs)
564    }
565}
566
567impl DivAssign<Decimal128> for Decimal128 {
568    fn div_assign(&mut self, rhs: Decimal128) {
569        *self = Context::<Decimal128>::default().div(*self, rhs);
570    }
571}
572
573impl Mul<Decimal128> for Decimal128 {
574    type Output = Decimal128;
575
576    fn mul(self, rhs: Decimal128) -> Decimal128 {
577        Context::<Decimal128>::default().mul(self, rhs)
578    }
579}
580
581impl MulAssign<Decimal128> for Decimal128 {
582    fn mul_assign(&mut self, rhs: Decimal128) {
583        *self = Context::<Decimal128>::default().mul(*self, rhs);
584    }
585}
586
587impl Rem<Decimal128> for Decimal128 {
588    type Output = Decimal128;
589
590    fn rem(self, rhs: Decimal128) -> Decimal128 {
591        Context::<Decimal128>::default().rem(self, rhs)
592    }
593}
594
595impl RemAssign<Decimal128> for Decimal128 {
596    fn rem_assign(&mut self, rhs: Decimal128) {
597        *self = Context::<Decimal128>::default().rem(*self, rhs);
598    }
599}
600
601impl Sub<Decimal128> for Decimal128 {
602    type Output = Decimal128;
603
604    fn sub(self, rhs: Decimal128) -> Decimal128 {
605        Context::<Decimal128>::default().sub(self, rhs)
606    }
607}
608
609impl SubAssign<Decimal128> for Decimal128 {
610    fn sub_assign(&mut self, rhs: Decimal128) {
611        *self = Context::<Decimal128>::default().sub(*self, rhs);
612    }
613}
614
615impl Sum for Decimal128 {
616    fn sum<I>(iter: I) -> Self
617    where
618        I: Iterator<Item = Decimal128>,
619    {
620        let mut cx = Context::<Decimal128>::default();
621        let mut sum = Decimal128::ZERO;
622        for d in iter {
623            sum = cx.add(sum, d);
624        }
625        sum
626    }
627}
628
629impl<'a> Sum<&'a Decimal128> for Decimal128 {
630    fn sum<I>(iter: I) -> Self
631    where
632        I: Iterator<Item = &'a Decimal128>,
633    {
634        iter.copied().sum()
635    }
636}
637
638impl Product for Decimal128 {
639    fn product<I>(iter: I) -> Self
640    where
641        I: Iterator<Item = Decimal128>,
642    {
643        let mut cx = Context::<Decimal128>::default();
644        let mut product = Decimal128::ONE;
645        for d in iter {
646            product = cx.mul(product, d);
647        }
648        product
649    }
650}
651
652impl<'a> Product<&'a Decimal128> for Decimal128 {
653    fn product<I>(iter: I) -> Self
654    where
655        I: Iterator<Item = &'a Decimal128>,
656    {
657        iter.copied().product()
658    }
659}
660
661impl Default for Context<Decimal128> {
662    fn default() -> Context<Decimal128> {
663        let mut ctx = MaybeUninit::<decnumber_sys::decContext>::uninit();
664        let ctx = unsafe {
665            decnumber_sys::decContextDefault(ctx.as_mut_ptr(), decnumber_sys::DEC_INIT_DECQUAD);
666            ctx.assume_init()
667        };
668        Context {
669            inner: ctx,
670            _phantom: PhantomData,
671        }
672    }
673}
674
675impl Context<Decimal128> {
676    /// Parses a number from its string representation.
677    pub fn parse<S>(&mut self, s: S) -> Result<Decimal128, ParseDecimalError>
678    where
679        S: Into<Vec<u8>>,
680    {
681        let c_string = CString::new(s).map_err(|_| ParseDecimalError)?;
682        let mut d = Decimal128::ZERO;
683        unsafe {
684            decnumber_sys::decQuadFromString(&mut d.inner, c_string.as_ptr(), &mut self.inner);
685        }
686        if (self.inner.status & decnumber_sys::DEC_Conversion_syntax) != 0 {
687            Err(ParseDecimalError)
688        } else {
689            Ok(d)
690        }
691    }
692
693    /// Constructs a number from an arbitrary-precision decimal.
694    ///
695    /// The result may be inexact. The status fields on the context will be set
696    /// appropriately if so.
697    pub fn from_decimal<const N: usize>(&mut self, d: &Decimal<N>) -> Decimal128 {
698        let mut d128 = Decimal128::ZERO;
699        unsafe {
700            decnumber_sys::decimal128FromNumber(&mut d128.inner, d.as_ptr(), &mut self.inner);
701        }
702        d128
703    }
704
705    /// Constructs a number from an `i128`.
706    ///
707    /// Note that this function can return inexact results for numbers with 35
708    /// or more places of precision, e.g.
709    /// `99_999_999_999_999_999_999_999_999_999_999_999i128`,
710    /// `-99_999_999_999_999_999_999_999_999_999_999_999i128`, `i128::MAX`,
711    /// `i128::MIN`, etc.
712    ///
713    /// However, some numbers with 35 or more places of precision retain their
714    /// exactness, e.g. `10_000_000_000_000_000_000_000_000_000_000_000i128`.
715    ///
716    /// ```
717    /// use dec::Decimal128;
718    /// let mut ctx = dec::Context::<Decimal128>::default();
719    /// let d = ctx.from_i128(-99_999_999_999_999_999_999_999_999_999_999_999i128);
720    /// // Inexact result
721    /// assert!(ctx.status().inexact());
722    ///
723    /// let mut ctx = dec::Context::<Decimal128>::default();
724    /// let d = ctx.from_i128(10_000_000_000_000_000_000_000_000_000_000_000i128);
725    /// // Exact result
726    /// assert!(!ctx.status().inexact());
727    /// ```
728    ///
729    /// To avoid inexact results when converting from large `i64`, use
730    /// [`crate::Decimal128`] instead.
731    pub fn from_i128(&mut self, n: i128) -> Decimal128 {
732        from_signed_int!(Decimal128, self, n)
733    }
734
735    /// Constructs a number from an `u128`.
736    ///
737    /// Note that this function can return inexact results for numbers with 35
738    /// or more places of precision, e.g.,
739    /// `10_000_000_000_000_000_000_000_000_000_000_001u128` and `u128::MAX`.
740    ///
741    /// However, some numbers with 15 or more places of precision retain their
742    /// exactness, e.g. `10_000_000_000_000_000_000_000_000_000_000_000u128`.
743    ///
744    /// ```
745    /// use dec::Decimal128;
746    /// let mut ctx = dec::Context::<Decimal128>::default();
747    /// let d = ctx.from_i128(10_000_000_000_000_000_000_000_000_000_000_001i128);
748    /// // Inexact result
749    /// assert!(ctx.status().inexact());
750    ///
751    /// let mut ctx = dec::Context::<Decimal128>::default();
752    /// let d = ctx.from_i128(10_000_000_000_000_000_000_000_000_000_000_000i128);
753    /// // Exact result
754    /// assert!(!ctx.status().inexact());
755    /// ```
756    pub fn from_u128(&mut self, n: u128) -> Decimal128 {
757        from_unsigned_int!(Decimal128, self, n)
758    }
759
760    /// Computes the absolute value of `n`.
761    ///
762    /// This has the same effect as [`Context::<Decimal128>::plus`] unless
763    /// `n` is negative, in which case it has the same effect as
764    /// [`Context::<Decimal128>::minus`].
765    ///
766    /// The returned result will be canonical.
767    pub fn abs(&mut self, mut n: Decimal128) -> Decimal128 {
768        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
769        unsafe {
770            decnumber_sys::decQuadAbs(n_inner, n_inner, &mut self.inner);
771        }
772        n
773    }
774
775    /// Adds `lhs` and `rhs`.
776    pub fn add(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
777        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
778        unsafe {
779            decnumber_sys::decQuadAdd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
780        }
781        lhs
782    }
783
784    /// Carries out the digitwise logical and of `lhs` and `rhs`.
785    ///
786    /// The operands must be valid for logical operations.
787    /// See [`Decimal128::is_logical`].
788    pub fn and(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
789        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
790        unsafe {
791            decnumber_sys::decQuadAnd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
792        }
793        lhs
794    }
795
796    /// Divides `lhs` by `rhs`.
797    pub fn div(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
798        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
799        unsafe {
800            decnumber_sys::decQuadDivide(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
801        }
802        lhs
803    }
804
805    /// Divides `lhs` by `rhs` and returns the integer part of the result
806    /// (rounded towards zero) with an exponent of 0.
807    ///
808    /// If the result would overflow, then [`Status::division_impossible`] is
809    /// set.
810    ///
811    /// [`Status::division_impossible`]: crate::context::Status::division_impossible
812    pub fn div_integer(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
813        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
814        unsafe {
815            decnumber_sys::decQuadDivideInteger(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
816        }
817        lhs
818    }
819
820    /// Calculates the fused multiply-add `(x * y) + z`.
821    ///
822    /// The multiplication is carried out first and is exact, so this operation
823    /// only has the one, final rounding.
824    pub fn fma(&mut self, mut x: Decimal128, y: Decimal128, z: Decimal128) -> Decimal128 {
825        let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
826        unsafe {
827            decnumber_sys::decQuadFMA(x_inner, x_inner, &y.inner, &z.inner, &mut self.inner);
828        }
829        x
830    }
831
832    /// Carries out the digitwise logical inversion of `n`.
833    ///
834    /// The operand must be valid for logical operation.
835    /// See [`Decimal128::is_logical`].
836    pub fn invert(&mut self, mut n: Decimal128) -> Decimal128 {
837        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
838        unsafe {
839            decnumber_sys::decQuadInvert(n_inner, n_inner, &mut self.inner);
840        }
841        n
842    }
843
844    /// Computes the adjusted exponent of the number, according to IEEE 754
845    /// rules.
846    pub fn logb(&mut self, mut n: Decimal128) -> Decimal128 {
847        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
848        unsafe {
849            decnumber_sys::decQuadLogB(n_inner, n_inner, &mut self.inner);
850        }
851        n
852    }
853
854    /// Returns whichever of `lhs` and `rhs` is larger.
855    ////
856    /// The comparison is performed using the same rules as for
857    /// [`Decimal128::total_cmp`].
858    pub fn max(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
859        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
860        unsafe {
861            decnumber_sys::decQuadMax(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
862        }
863        lhs
864    }
865
866    /// Returns whichever of `lhs` and `rhs` has the largest absolute value.
867    pub fn max_abs(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
868        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
869        unsafe {
870            decnumber_sys::decQuadMaxMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
871        }
872        lhs
873    }
874
875    /// Returns whichever of `lhs` and `rhs` is smaller.
876    ////
877    /// The comparison is performed using the same rules as for
878    /// [`Decimal128::total_cmp`].
879    pub fn min(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
880        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
881
882        unsafe {
883            decnumber_sys::decQuadMin(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
884        }
885        lhs
886    }
887
888    /// Returns whichever of `lhs` and `rhs` has the largest absolute value.
889    pub fn min_abs(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
890        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
891        unsafe {
892            decnumber_sys::decQuadMinMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
893        }
894        lhs
895    }
896
897    /// Subtracts `n` from zero.
898    pub fn minus(&mut self, mut n: Decimal128) -> Decimal128 {
899        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
900        unsafe {
901            decnumber_sys::decQuadMinus(n_inner, n_inner, &mut self.inner);
902        }
903        n
904    }
905
906    /// Multiplies `lhs` by `rhs`.
907    pub fn mul(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
908        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
909        unsafe {
910            decnumber_sys::decQuadMultiply(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
911        }
912        lhs
913    }
914
915    /// Returns the next number to `n` in the direction of negative infinity.
916    ///
917    /// This operation follows the IEEE 754 rules for the *nextDown* operation.
918    pub fn next_minus(&mut self, mut n: Decimal128) -> Decimal128 {
919        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
920        unsafe {
921            decnumber_sys::decQuadNextMinus(n_inner, n_inner, &mut self.inner);
922        }
923        n
924    }
925
926    /// Returns the next number to `n` in the direction of positive infinity.
927    ///
928    /// This operation follows the IEEE 754 rules for the *nextUp* operation.
929    pub fn next_plus(&mut self, mut n: Decimal128) -> Decimal128 {
930        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
931        unsafe {
932            decnumber_sys::decQuadNextPlus(n_inner, n_inner, &mut self.inner);
933        }
934        n
935    }
936
937    /// Returns the next number to `x` in the direction of `y`.
938    ///
939    /// This operation follows the IEEE 754 rules for the *nextAfter* operation.
940    pub fn next_toward(&mut self, mut x: Decimal128, y: Decimal128) -> Decimal128 {
941        let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
942        unsafe {
943            decnumber_sys::decQuadNextToward(x_inner, x_inner, &y.inner, &mut self.inner);
944        }
945        x
946    }
947
948    /// Determines the ordering of `lhs` relative to `rhs`, using a partial
949    /// order.
950    ///
951    /// If either `lhs` or `rhs` is a NaN, returns `None`. To force an ordering
952    /// upon NaNs, use [`Decimal128::total_cmp`].
953    pub fn partial_cmp(&mut self, lhs: Decimal128, rhs: Decimal128) -> Option<Ordering> {
954        let mut d = Decimal128::ZERO;
955        unsafe {
956            decnumber_sys::decQuadCompare(&mut d.inner, &lhs.inner, &rhs.inner, &mut self.inner);
957        }
958        if d.is_positive() {
959            Some(Ordering::Greater)
960        } else if d.is_negative() {
961            Some(Ordering::Less)
962        } else if d.is_zero() {
963            Some(Ordering::Equal)
964        } else {
965            debug_assert!(d.is_nan());
966            None
967        }
968    }
969
970    /// Adds `n` to zero.
971    pub fn plus(&mut self, mut n: Decimal128) -> Decimal128 {
972        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
973        unsafe {
974            decnumber_sys::decQuadPlus(n_inner, n_inner, &mut self.inner);
975        }
976        n
977    }
978
979    /// Rounds or pads `lhs` so that it has the same exponent as `rhs`.
980    pub fn quantize(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
981        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
982        unsafe {
983            decnumber_sys::decQuadQuantize(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
984        }
985        lhs
986    }
987
988    /// Reduces the number's coefficient to its shortest possible form without
989    /// changing the value of the result.
990    ///
991    /// This removes all possible trailing zeros; some may remain when the
992    /// number is very close to the most positive or most negative number.
993    pub fn reduce(&mut self, mut n: Decimal128) -> Decimal128 {
994        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
995        unsafe {
996            decnumber_sys::decQuadReduce(n_inner, n_inner, &mut self.inner);
997        }
998        n
999    }
1000
1001    /// Integer-divides `lhs` by `rhs` and returns the remainder from the
1002    /// division.
1003    pub fn rem(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1004        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1005        unsafe {
1006            decnumber_sys::decQuadRemainder(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1007        }
1008        lhs
1009    }
1010
1011    /// Like [`rem`](Context::<Decimal128>::rem), but uses the IEEE 754
1012    /// rules for remainder operations.
1013    pub fn rem_near(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1014        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1015        unsafe {
1016            decnumber_sys::decQuadRemainderNear(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1017        }
1018        lhs
1019    }
1020
1021    /// Rotates the digits of `lhs` by `rhs`.
1022    ///
1023    /// If `rhs` is positive, rotates to the left. If `rhs` is negative, rotates
1024    /// to the right.
1025    ///
1026    /// `rhs` specifies the number of positions to rotate, and must be a finite
1027    /// integer. NaNs are propagated as usual.
1028    ///
1029    /// If `lhs` is infinity, the result is infinity of the same sign.
1030    pub fn rotate(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1031        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1032        unsafe {
1033            decnumber_sys::decQuadRotate(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1034        }
1035        lhs
1036    }
1037
1038    /// Rounds the number to an integral value using the rounding mode in
1039    /// the context.
1040    pub fn round(&mut self, mut n: Decimal128) -> Decimal128 {
1041        let n_inner = &mut n.inner as *mut decnumber_sys::decQuad;
1042        unsafe {
1043            decnumber_sys::decQuadToIntegralExact(n_inner, n_inner, &mut self.inner);
1044        }
1045        n
1046    }
1047
1048    /// Multiplies `x` by 10<sup>`y`</sup>.
1049    pub fn scaleb(&mut self, mut x: Decimal128, y: Decimal128) -> Decimal128 {
1050        let x_inner = &mut x.inner as *mut decnumber_sys::decQuad;
1051        unsafe {
1052            decnumber_sys::decQuadScaleB(x_inner, x_inner, &y.inner, &mut self.inner);
1053        }
1054        x
1055    }
1056
1057    /// Sets `d`'s exponent to `e` _without_ modifying the coefficient.
1058    pub fn set_exponent(&mut self, d: &mut Decimal128, e: i32) {
1059        unsafe {
1060            decnumber_sys::decQuadSetExponent(&mut d.inner, &mut self.inner, e);
1061        }
1062    }
1063
1064    /// Shifts the digits of `lhs` by `rhs`.
1065    ///
1066    /// If `rhs` is positive, shifts to the left. If `rhs` is negative, shifts
1067    /// to the right. Any digits "shifted in" will be zero.
1068    ///
1069    /// `rhs` specifies the number of positions to shift, and must be a finite
1070    /// integer. NaNs are propagated as usual.
1071    ///
1072    /// If `lhs` is infinity, the result is infinity of the same sign.
1073    pub fn shift(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1074        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1075        unsafe {
1076            decnumber_sys::decQuadShift(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1077        }
1078        lhs
1079    }
1080
1081    /// Adjust `x`'s exponent to equal `s`, while retaining as many of the same
1082    /// significant digits of the coefficient as permitted with the current and
1083    /// new exponents.
1084    ///
1085    /// - When increasing the exponent's value, **irrevocably truncates** the least
1086    ///   significant digits. Use caution in this context.
1087    /// - When reducing the exponent's value, appends `0`s as less significant
1088    ///   digits.
1089    ///
1090    /// ```
1091    /// use dec::{Context, Decimal128};
1092    /// let mut cx = Context::<Decimal128>::default();
1093    /// let mut d = cx.div(Decimal128::from(5), Decimal128::from(4));
1094    ///
1095    /// assert_eq!(d.exponent(), -2);
1096    /// assert_eq!(d.to_string(), "1.25");
1097    ///
1098    /// cx.rescale(&mut d, -3);
1099    /// assert_eq!(d.exponent(), -3);
1100    /// assert_eq!(d.to_string(), "1.250");
1101    ///
1102    /// cx.rescale(&mut d, -1);
1103    /// assert_eq!(d.exponent(), -1);
1104    /// assert_eq!(d.to_string(), "1.2");
1105    ///
1106    /// cx.rescale(&mut d, 0);
1107    /// assert_eq!(d.exponent(), 0);
1108    /// assert_eq!(d.to_string(), "1");
1109    /// ```
1110    pub fn rescale(&mut self, x: &mut Decimal128, s: i32) {
1111        let e = x.exponent();
1112        *x = self.shift(*x, Decimal128::from(e - s));
1113        self.set_exponent(x, s);
1114    }
1115
1116    /// Subtracts `rhs` from `lhs`.
1117    pub fn sub(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1118        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1119        unsafe {
1120            decnumber_sys::decQuadSubtract(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1121        }
1122        lhs
1123    }
1124
1125    /// Carries out the digitwise logical or of `lhs` and `rhs`.
1126    ///
1127    /// The operands must be valid for logical operations.
1128    /// See [`Decimal128::is_logical`].
1129    pub fn or(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1130        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1131        unsafe {
1132            decnumber_sys::decQuadOr(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1133        }
1134        lhs
1135    }
1136
1137    /// Carries out the digitwise logical exclusive or of `lhs` and `rhs`.
1138    ///
1139    /// The operands must be valid for logical operations.
1140    /// See [`Decimal128::is_logical`].
1141    pub fn xor(&mut self, mut lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
1142        let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decQuad;
1143        unsafe {
1144            decnumber_sys::decQuadXor(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1145        }
1146        lhs
1147    }
1148}
1149
1150#[cfg(feature = "num-traits")]
1151impl One for Decimal128 {
1152    #[inline]
1153    fn one() -> Self {
1154        Self::ONE
1155    }
1156}
1157
1158#[cfg(feature = "num-traits")]
1159impl Zero for Decimal128 {
1160    #[inline]
1161    fn zero() -> Self {
1162        Self::ZERO
1163    }
1164
1165    #[inline]
1166    fn is_zero(&self) -> bool {
1167        self.is_zero()
1168    }
1169}
1170
1171#[cfg(feature = "num-traits")]
1172impl MulAdd for Decimal128 {
1173    type Output = Self;
1174
1175    fn mul_add(self, a: Self, b: Self) -> Self::Output {
1176        Context::<Self>::default().fma(self, a, b)
1177    }
1178}
1179
1180#[cfg(feature = "num-traits")]
1181impl MulAddAssign for Decimal128 {
1182    #[inline]
1183    fn mul_add_assign(&mut self, a: Self, b: Self) {
1184        *self = self.mul_add(a, b)
1185    }
1186}