1use 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::decimal128::Decimal128;
36use crate::decimal32::Decimal32;
37use crate::error::ParseDecimalError;
38
39#[repr(transparent)]
59#[derive(Clone, Copy)]
60pub struct Decimal64 {
61 pub(crate) inner: decnumber_sys::decDouble,
62}
63
64impl Decimal64 {
65 pub const NAN: Decimal64 = Decimal64::from_ne_bytes(if cfg!(target_endian = "little") {
67 [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c]
68 } else {
69 [0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
70 });
71
72 pub const ZERO: Decimal64 = Decimal64::from_ne_bytes(if cfg!(target_endian = "little") {
74 [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x22]
75 } else {
76 [0x22, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
77 });
78
79 pub const ONE: Decimal64 = Decimal64::from_ne_bytes(if cfg!(target_endian = "little") {
81 [0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x22]
82 } else {
83 [0x22, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]
84 });
85
86 const TWO_POW_32: Decimal64 = Decimal64::from_ne_bytes(if cfg!(target_endian = "little") {
88 [0x7A, 0xB5, 0xAF, 0x15, 0x1, 0x0, 0x38, 0x22]
89 } else {
90 [0x22, 0x38, 0x0, 0x1, 0x15, 0xAF, 0xB5, 0x7A]
91 });
92
93 pub fn from_le_bytes(mut bytes: [u8; 8]) -> Decimal64 {
95 if cfg!(target_endian = "big") {
96 bytes.reverse();
97 }
98 Decimal64::from_ne_bytes(bytes)
99 }
100
101 pub fn from_be_bytes(mut bytes: [u8; 8]) -> Decimal64 {
103 if cfg!(target_endian = "little") {
104 bytes.reverse();
105 }
106 Decimal64::from_ne_bytes(bytes)
107 }
108
109 pub const fn from_ne_bytes(bytes: [u8; 8]) -> Decimal64 {
112 Decimal64 {
113 inner: decnumber_sys::decDouble { bytes },
114 }
115 }
116
117 pub fn to_le_bytes(&self) -> [u8; 8] {
120 let mut bytes = self.to_ne_bytes();
121 if cfg!(target_endian = "big") {
122 bytes.reverse();
123 }
124 bytes
125 }
126
127 pub fn to_be_bytes(&self) -> [u8; 8] {
130 let mut bytes = self.to_ne_bytes();
131 if cfg!(target_endian = "little") {
132 bytes.reverse();
133 }
134 bytes
135 }
136
137 pub fn to_ne_bytes(&self) -> [u8; 8] {
140 self.inner.bytes
141 }
142
143 pub fn class(&self) -> Class {
145 Class::from_c(unsafe { decnumber_sys::decDoubleClass(&self.inner) })
146 }
147
148 pub fn digits(&self) -> u32 {
153 unsafe { decnumber_sys::decDoubleDigits(&self.inner) }
154 }
155
156 pub fn coefficient(&self) -> i64 {
160 let mut dpd = if cfg!(target_endian = "big") {
161 u64::from_be_bytes(self.inner.bytes)
162 } else {
163 u64::from_le_bytes(self.inner.bytes)
164 };
165
166 let dpd_mask = 0b11_1111_1111;
168
169 let mut r = i64::from(unsafe { decnumber_sys::DPD2BIN[dpd as usize & dpd_mask] });
173 dpd >>= 10;
174 r += i64::from(unsafe { decnumber_sys::DPD2BINK[dpd as usize & dpd_mask] });
175 dpd >>= 10;
176 r += i64::from(unsafe { decnumber_sys::DPD2BINM[dpd as usize & dpd_mask] });
177 dpd >>= 10;
178
179 let mut r_1: i64 = 0;
181 r_1 += i64::from(unsafe { decnumber_sys::DPD2BIN[dpd as usize & dpd_mask] });
182 dpd >>= 10;
183 r_1 += i64::from(unsafe { decnumber_sys::DPD2BINK[dpd as usize & dpd_mask] });
184
185 r += r_1 * 10_000_000_00;
186
187 let h = i64::from(unsafe { decnumber_sys::DECCOMBMSD[(dpd >> 18) as usize] });
189
190 if h > 0 {
191 r += h * 1_000_000_000_000_000;
192 }
193
194 if self.is_negative() {
195 r *= -1;
196 }
197
198 r
199 }
200
201 pub fn coefficient_digits(&self) -> [u8; decnumber_sys::DECDOUBLE_Pmax] {
206 let mut buf = [0u8; decnumber_sys::DECDOUBLE_Pmax];
207 unsafe {
208 decnumber_sys::decDoubleGetCoefficient(&self.inner, buf.as_mut_ptr() as *mut u8);
209 }
210 buf
211 }
212
213 pub fn exponent(&self) -> i32 {
215 unsafe { decnumber_sys::decDoubleGetExponent(&self.inner) }
216 }
217
218 pub fn canonical(mut self) -> Decimal64 {
221 unsafe {
222 decnumber_sys::decDoubleCanonical(&mut self.inner, &self.inner);
223 }
224 self
225 }
226
227 pub fn is_canonical(&self) -> bool {
229 unsafe { decnumber_sys::decDoubleIsCanonical(&self.inner) != 0 }
230 }
231
232 pub fn is_finite(&self) -> bool {
236 unsafe { decnumber_sys::decDoubleIsFinite(&self.inner) != 0 }
237 }
238
239 pub fn is_infinite(&self) -> bool {
241 unsafe { decnumber_sys::decDoubleIsInfinite(&self.inner) != 0 }
242 }
243
244 pub fn is_integer(&self) -> bool {
249 unsafe { decnumber_sys::decDoubleIsInteger(&self.inner) != 0 }
250 }
251
252 pub fn is_logical(&self) -> bool {
257 unsafe { decnumber_sys::decDoubleIsInteger(&self.inner) != 0 }
258 }
259
260 pub fn is_nan(&self) -> bool {
262 unsafe { decnumber_sys::decDoubleIsNaN(&self.inner) != 0 }
263 }
264
265 pub fn is_negative(&self) -> bool {
267 unsafe { decnumber_sys::decDoubleIsNegative(&self.inner) != 0 }
268 }
269
270 pub fn is_normal(&self) -> bool {
274 unsafe { decnumber_sys::decDoubleIsNormal(&self.inner) != 0 }
275 }
276
277 pub fn is_positive(&self) -> bool {
279 unsafe { decnumber_sys::decDoubleIsPositive(&self.inner) != 0 }
280 }
281
282 pub fn is_signaling_nan(&self) -> bool {
284 unsafe { decnumber_sys::decDoubleIsSignaling(&self.inner) != 0 }
285 }
286
287 pub fn is_signed(&self) -> bool {
291 unsafe { decnumber_sys::decDoubleIsSigned(&self.inner) != 0 }
292 }
293
294 pub fn is_subnormal(&self) -> bool {
299 unsafe { decnumber_sys::decDoubleIsSubnormal(&self.inner) != 0 }
300 }
301
302 pub fn is_zero(&self) -> bool {
304 unsafe { decnumber_sys::decDoubleIsZero(&self.inner) != 0 }
305 }
306
307 pub fn quantum_matches(&self, rhs: &Decimal64) -> bool {
313 unsafe { decnumber_sys::decDoubleSameQuantum(&self.inner, &rhs.inner) != 0 }
314 }
315
316 pub fn total_cmp(&self, rhs: &Decimal64) -> Ordering {
321 let mut d = Decimal64::ZERO;
322 unsafe {
323 decnumber_sys::decDoubleCompareTotal(&mut d.inner, &self.inner, &rhs.inner);
324 }
325 if d.is_positive() {
326 Ordering::Greater
327 } else if d.is_negative() {
328 Ordering::Less
329 } else {
330 debug_assert!(d.is_zero());
331 Ordering::Equal
332 }
333 }
334
335 pub fn to_standard_notation_string(&self) -> String {
338 if !self.is_finite() {
339 return self.to_string();
340 }
341 let mut digits = [b'0'; decnumber_sys::DECDOUBLE_Pmax];
342 let mut digits_idx = 0;
343 let (sourlo, sourhi) = if cfg!(target_endian = "little") {
344 (
345 u32::from_le_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
346 u32::from_le_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
347 )
348 } else {
349 (
350 u32::from_be_bytes(self.inner.bytes[4..8].try_into().unwrap()) as usize,
351 u32::from_be_bytes(self.inner.bytes[0..4].try_into().unwrap()) as usize,
352 )
353 };
354
355 let comb = ((sourhi >> 26) & 0x1f) as usize;
356 let msd = unsafe { decnumber_sys::DECCOMBMSD[comb] };
357
358 if msd > 0 {
359 digits[digits_idx] = b'0' + msd as u8;
360 digits_idx += 1;
361 }
362
363 #[allow(unused_assignments)]
364 let mut dpd: usize = 0;
365
366 dpd = (sourhi >> 8) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
368
369 dpd = ((sourhi & 0xff) << 2) | (sourlo >> 30); dpd2char!(dpd, digits, digits_idx);
371
372 dpd = (sourlo >> 20) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
374
375 dpd = (sourlo >> 10) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
377
378 dpd = (sourlo) & 0x3ff; dpd2char!(dpd, digits, digits_idx);
380
381 stringify_digits!(self, digits, digits_idx)
382 }
383}
384
385#[test]
386fn test() {
387 let mut cx = Context::<Decimal64>::default();
388 let d = cx.parse("0").unwrap();
389 println!("{:?}", d.to_standard_notation_string());
390}
391
392impl Default for Decimal64 {
393 fn default() -> Decimal64 {
394 Decimal64::ZERO
395 }
396}
397
398impl fmt::Debug for Decimal64 {
399 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
400 fmt::Display::fmt(self, f)
401 }
402}
403
404impl fmt::Display for Decimal64 {
405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406 let mut buf = ['\0'; decnumber_sys::DECDOUBLE_String];
407 let c_str = unsafe {
408 if f.alternate() {
409 decnumber_sys::decDoubleToEngString(&self.inner, buf.as_mut_ptr() as *mut c_char);
410 } else {
411 decnumber_sys::decDoubleToString(&self.inner, buf.as_mut_ptr() as *mut c_char);
412 }
413 CStr::from_ptr(buf.as_ptr() as *const c_char)
414 };
415 f.write_str(
416 c_str
417 .to_str()
418 .expect("decDoubleToString yields valid UTF-8"),
419 )
420 }
421}
422
423impl FromStr for Decimal64 {
424 type Err = ParseDecimalError;
425
426 fn from_str(s: &str) -> Result<Decimal64, ParseDecimalError> {
427 Context::<Decimal64>::default().parse(s)
428 }
429}
430
431impl From<i32> for Decimal64 {
432 fn from(n: i32) -> Decimal64 {
433 let mut d = Decimal64::ZERO;
434 unsafe {
435 decnumber_sys::decDoubleFromInt32(&mut d.inner, n);
436 };
437 d
438 }
439}
440
441impl From<u32> for Decimal64 {
442 fn from(n: u32) -> Decimal64 {
443 let mut d = Decimal64::ZERO;
444 unsafe {
445 decnumber_sys::decDoubleFromUInt32(&mut d.inner, n);
446 };
447 d
448 }
449}
450
451impl From<Decimal32> for Decimal64 {
452 fn from(d32: Decimal32) -> Decimal64 {
453 let mut d64 = Decimal64::ZERO;
454 unsafe {
455 decnumber_sys::decSingleToWider(&d32.inner, &mut d64.inner);
456 }
457 d64
458 }
459}
460
461impl PartialOrd for Decimal64 {
462 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
463 Context::<Decimal64>::default().partial_cmp(*self, *other)
464 }
465}
466
467impl PartialEq for Decimal64 {
468 fn eq(&self, other: &Self) -> bool {
469 self.partial_cmp(other) == Some(Ordering::Equal)
470 }
471}
472
473impl Neg for Decimal64 {
474 type Output = Decimal64;
475
476 fn neg(self) -> Decimal64 {
477 Context::<Decimal64>::default().minus(self)
478 }
479}
480
481impl Add<Decimal64> for Decimal64 {
482 type Output = Decimal64;
483
484 fn add(self, rhs: Decimal64) -> Decimal64 {
485 Context::<Decimal64>::default().add(self, rhs)
486 }
487}
488
489impl AddAssign<Decimal64> for Decimal64 {
490 fn add_assign(&mut self, rhs: Decimal64) {
491 *self = Context::<Decimal64>::default().add(*self, rhs);
492 }
493}
494
495impl Div<Decimal64> for Decimal64 {
496 type Output = Decimal64;
497
498 fn div(self, rhs: Decimal64) -> Decimal64 {
499 Context::<Decimal64>::default().div(self, rhs)
500 }
501}
502
503impl DivAssign<Decimal64> for Decimal64 {
504 fn div_assign(&mut self, rhs: Decimal64) {
505 *self = Context::<Decimal64>::default().div(*self, rhs);
506 }
507}
508
509impl Mul<Decimal64> for Decimal64 {
510 type Output = Decimal64;
511
512 fn mul(self, rhs: Decimal64) -> Decimal64 {
513 Context::<Decimal64>::default().mul(self, rhs)
514 }
515}
516
517impl MulAssign<Decimal64> for Decimal64 {
518 fn mul_assign(&mut self, rhs: Decimal64) {
519 *self = Context::<Decimal64>::default().mul(*self, rhs);
520 }
521}
522
523impl Rem<Decimal64> for Decimal64 {
524 type Output = Decimal64;
525
526 fn rem(self, rhs: Decimal64) -> Decimal64 {
527 Context::<Decimal64>::default().rem(self, rhs)
528 }
529}
530
531impl RemAssign<Decimal64> for Decimal64 {
532 fn rem_assign(&mut self, rhs: Decimal64) {
533 *self = Context::<Decimal64>::default().rem(*self, rhs);
534 }
535}
536
537impl Sub<Decimal64> for Decimal64 {
538 type Output = Decimal64;
539
540 fn sub(self, rhs: Decimal64) -> Decimal64 {
541 Context::<Decimal64>::default().sub(self, rhs)
542 }
543}
544
545impl SubAssign<Decimal64> for Decimal64 {
546 fn sub_assign(&mut self, rhs: Decimal64) {
547 *self = Context::<Decimal64>::default().sub(*self, rhs);
548 }
549}
550
551impl Sum for Decimal64 {
552 fn sum<I>(iter: I) -> Self
553 where
554 I: Iterator<Item = Decimal64>,
555 {
556 let mut cx = Context::<Decimal64>::default();
557 let mut sum = Decimal64::ZERO;
558 for d in iter {
559 sum = cx.add(sum, d);
560 }
561 sum
562 }
563}
564
565impl<'a> Sum<&'a Decimal64> for Decimal64 {
566 fn sum<I>(iter: I) -> Self
567 where
568 I: Iterator<Item = &'a Decimal64>,
569 {
570 iter.copied().sum()
571 }
572}
573
574impl Product for Decimal64 {
575 fn product<I>(iter: I) -> Self
576 where
577 I: Iterator<Item = Decimal64>,
578 {
579 let mut cx = Context::<Decimal64>::default();
580 let mut product = Decimal64::ONE;
581 for d in iter {
582 product = cx.mul(product, d);
583 }
584 product
585 }
586}
587
588impl<'a> Product<&'a Decimal64> for Decimal64 {
589 fn product<I>(iter: I) -> Self
590 where
591 I: Iterator<Item = &'a Decimal64>,
592 {
593 iter.copied().product()
594 }
595}
596
597impl Default for Context<Decimal64> {
598 fn default() -> Context<Decimal64> {
599 let mut ctx = MaybeUninit::<decnumber_sys::decContext>::uninit();
600 let ctx = unsafe {
601 decnumber_sys::decContextDefault(ctx.as_mut_ptr(), decnumber_sys::DEC_INIT_DECDOUBLE);
602 ctx.assume_init()
603 };
604 Context {
605 inner: ctx,
606 _phantom: PhantomData,
607 }
608 }
609}
610
611impl Context<Decimal64> {
612 pub fn parse<S>(&mut self, s: S) -> Result<Decimal64, ParseDecimalError>
614 where
615 S: Into<Vec<u8>>,
616 {
617 let c_string = CString::new(s).map_err(|_| ParseDecimalError)?;
618 let mut d = Decimal64::ZERO;
619 unsafe {
620 decnumber_sys::decDoubleFromString(&mut d.inner, c_string.as_ptr(), &mut self.inner);
621 };
622 if (self.inner.status & decnumber_sys::DEC_Conversion_syntax) != 0 {
623 Err(ParseDecimalError)
624 } else {
625 Ok(d)
626 }
627 }
628
629 pub fn from_decimal128(&mut self, d128: Decimal128) -> Decimal64 {
634 let mut d64 = Decimal64::ZERO;
635 unsafe {
636 decnumber_sys::decDoubleFromWider(&mut d64.inner, &d128.inner, &mut self.inner);
637 };
638 d64
639 }
640
641 pub fn from_decimal<const N: usize>(&mut self, d: &Decimal<N>) -> Decimal64 {
646 let mut d64 = Decimal64::ZERO;
647 unsafe {
648 decnumber_sys::decimal64FromNumber(&mut d64.inner, d.as_ptr(), &mut self.inner);
649 };
650 d64
651 }
652
653 pub fn from_i64(&mut self, n: i64) -> Decimal64 {
678 from_signed_int!(Decimal64, self, n)
679 }
680
681 pub fn from_u64(&mut self, n: u64) -> Decimal64 {
706 from_unsigned_int!(Decimal64, self, n)
707 }
708
709 pub fn abs(&mut self, mut n: Decimal64) -> Decimal64 {
717 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
718 unsafe {
719 decnumber_sys::decDoubleAbs(n_inner, n_inner, &mut self.inner);
720 }
721 n
722 }
723
724 pub fn add(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
726 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
727 unsafe {
728 decnumber_sys::decDoubleAdd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
729 }
730 lhs
731 }
732
733 pub fn and(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
738 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
739 unsafe {
740 decnumber_sys::decDoubleAnd(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
741 }
742 lhs
743 }
744
745 pub fn div(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
747 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
748 unsafe {
749 decnumber_sys::decDoubleDivide(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
750 }
751 lhs
752 }
753
754 pub fn div_integer(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
762 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
763 unsafe {
764 decnumber_sys::decDoubleDivideInteger(
765 lhs_inner,
766 lhs_inner,
767 &rhs.inner,
768 &mut self.inner,
769 );
770 }
771 lhs
772 }
773
774 pub fn fma(&mut self, mut x: Decimal64, y: Decimal64, z: Decimal64) -> Decimal64 {
779 let x_inner = &mut x.inner as *mut decnumber_sys::decDouble;
780 unsafe {
781 decnumber_sys::decDoubleFMA(x_inner, x_inner, &y.inner, &z.inner, &mut self.inner);
782 }
783 x
784 }
785
786 pub fn invert(&mut self, mut n: Decimal64) -> Decimal64 {
791 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
792 unsafe {
793 decnumber_sys::decDoubleInvert(n_inner, n_inner, &mut self.inner);
794 }
795 n
796 }
797
798 pub fn logb(&mut self, mut n: Decimal64) -> Decimal64 {
801 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
802 unsafe {
803 decnumber_sys::decDoubleLogB(n_inner, n_inner, &mut self.inner);
804 }
805 n
806 }
807
808 pub fn max(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
813 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
814 unsafe {
815 decnumber_sys::decDoubleMax(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
816 }
817 lhs
818 }
819
820 pub fn max_abs(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
822 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
823 unsafe {
824 decnumber_sys::decDoubleMaxMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
825 }
826 lhs
827 }
828
829 pub fn min(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
834 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
835 unsafe {
836 decnumber_sys::decDoubleMin(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
837 }
838 lhs
839 }
840
841 pub fn min_abs(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
843 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
844 unsafe {
845 decnumber_sys::decDoubleMinMag(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
846 }
847 lhs
848 }
849
850 pub fn minus(&mut self, mut n: Decimal64) -> Decimal64 {
852 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
853 unsafe {
854 decnumber_sys::decDoubleMinus(n_inner, n_inner, &mut self.inner);
855 }
856 n
857 }
858
859 pub fn mul(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
861 unsafe {
862 decnumber_sys::decDoubleMultiply(
863 &mut lhs.inner,
864 &lhs.inner,
865 &rhs.inner,
866 &mut self.inner,
867 );
868 }
869 lhs
870 }
871
872 pub fn next_minus(&mut self, mut n: Decimal64) -> Decimal64 {
876 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
877 unsafe {
878 decnumber_sys::decDoubleNextMinus(n_inner, n_inner, &mut self.inner);
879 }
880 n
881 }
882
883 pub fn next_plus(&mut self, mut n: Decimal64) -> Decimal64 {
887 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
888 unsafe {
889 decnumber_sys::decDoubleNextPlus(n_inner, n_inner, &mut self.inner);
890 }
891 n
892 }
893
894 pub fn next_toward(&mut self, mut x: Decimal64, y: Decimal64) -> Decimal64 {
898 let x_inner = &mut x.inner as *mut decnumber_sys::decDouble;
899 unsafe {
900 decnumber_sys::decDoubleNextToward(x_inner, x_inner, &y.inner, &mut self.inner);
901 }
902 x
903 }
904
905 pub fn partial_cmp(&mut self, lhs: Decimal64, rhs: Decimal64) -> Option<Ordering> {
912 let mut d = Decimal64::ZERO;
913 unsafe {
914 decnumber_sys::decDoubleCompare(&mut d.inner, &lhs.inner, &rhs.inner, &mut self.inner);
915 }
916 if d.is_positive() {
917 Some(Ordering::Greater)
918 } else if d.is_negative() {
919 Some(Ordering::Less)
920 } else if d.is_zero() {
921 Some(Ordering::Equal)
922 } else {
923 debug_assert!(d.is_nan());
924 None
925 }
926 }
927
928 pub fn plus(&mut self, mut n: Decimal64) -> Decimal64 {
930 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
931 unsafe {
932 decnumber_sys::decDoublePlus(n_inner, n_inner, &mut self.inner);
933 }
934 n
935 }
936
937 pub fn quantize(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
939 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
940 unsafe {
941 decnumber_sys::decDoubleQuantize(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
942 }
943 lhs
944 }
945
946 pub fn reduce(&mut self, mut n: Decimal64) -> Decimal64 {
952 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
953 unsafe {
954 decnumber_sys::decDoubleReduce(n_inner, n_inner, &mut self.inner);
955 }
956 n
957 }
958
959 pub fn rem(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
962 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
963 unsafe {
964 decnumber_sys::decDoubleRemainder(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
965 }
966 lhs
967 }
968
969 pub fn rem_near(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
972 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
973 unsafe {
974 decnumber_sys::decDoubleRemainderNear(
975 lhs_inner,
976 lhs_inner,
977 &rhs.inner,
978 &mut self.inner,
979 );
980 }
981 lhs
982 }
983
984 pub fn rotate(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
994 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
995 unsafe {
996 decnumber_sys::decDoubleRotate(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
997 }
998 lhs
999 }
1000
1001 pub fn round(&mut self, mut n: Decimal64) -> Decimal64 {
1004 let n_inner = &mut n.inner as *mut decnumber_sys::decDouble;
1005 unsafe {
1006 decnumber_sys::decDoubleToIntegralExact(n_inner, n_inner, &mut self.inner);
1007 }
1008 n
1009 }
1010
1011 pub fn scaleb(&mut self, mut x: Decimal64, y: Decimal64) -> Decimal64 {
1013 let x_inner = &mut x.inner as *mut decnumber_sys::decDouble;
1014 unsafe {
1015 decnumber_sys::decDoubleScaleB(x_inner, x_inner, &y.inner, &mut self.inner);
1016 }
1017 x
1018 }
1019
1020 pub fn set_exponent(&mut self, d: &mut Decimal64, e: i32) {
1022 unsafe {
1023 decnumber_sys::decDoubleSetExponent(&mut d.inner, &mut self.inner, e);
1024 }
1025 }
1026
1027 pub fn shift(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
1037 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
1038 unsafe {
1039 decnumber_sys::decDoubleShift(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1040 }
1041 lhs
1042 }
1043
1044 pub fn rescale(&mut self, x: &mut Decimal64, s: i32) {
1074 let e = x.exponent();
1075 *x = self.shift(*x, Decimal64::from(e - s));
1076 self.set_exponent(x, s);
1077 }
1078
1079 pub fn sub(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
1081 unsafe {
1082 decnumber_sys::decDoubleSubtract(
1083 &mut lhs.inner,
1084 &lhs.inner,
1085 &rhs.inner,
1086 &mut self.inner,
1087 );
1088 }
1089 lhs
1090 }
1091
1092 pub fn or(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
1097 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
1098 unsafe {
1099 decnumber_sys::decDoubleOr(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1100 }
1101 lhs
1102 }
1103
1104 pub fn xor(&mut self, mut lhs: Decimal64, rhs: Decimal64) -> Decimal64 {
1109 let lhs_inner = &mut lhs.inner as *mut decnumber_sys::decDouble;
1110 unsafe {
1111 decnumber_sys::decDoubleXor(lhs_inner, lhs_inner, &rhs.inner, &mut self.inner);
1112 }
1113 lhs
1114 }
1115}
1116
1117#[cfg(feature = "num-traits")]
1118impl One for Decimal64 {
1119 #[inline]
1120 fn one() -> Self {
1121 Self::ONE
1122 }
1123}
1124
1125#[cfg(feature = "num-traits")]
1126impl Zero for Decimal64 {
1127 #[inline]
1128 fn zero() -> Self {
1129 Self::ZERO
1130 }
1131
1132 #[inline]
1133 fn is_zero(&self) -> bool {
1134 self.is_zero()
1135 }
1136}
1137
1138#[cfg(feature = "num-traits")]
1139impl MulAdd for Decimal64 {
1140 type Output = Self;
1141
1142 fn mul_add(self, a: Self, b: Self) -> Self::Output {
1143 Context::<Self>::default().fma(self, a, b)
1144 }
1145}
1146
1147#[cfg(feature = "num-traits")]
1148impl MulAddAssign for Decimal64 {
1149 #[inline]
1150 fn mul_add_assign(&mut self, a: Self, b: Self) {
1151 *self = self.mul_add(a, b)
1152 }
1153}