Skip to main content

bigdecimal/generics/
with_scale.rs

1//! Add a scale to any type
2//!
3//! To scale means decorate the number with an i64 which implies
4//! multiplying by 10^-scale.
5//!
6
7use crate::*;
8use crate::arithmetic::*;
9
10
11/// pair i64 'scale' with some other value
12#[derive(#[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for WithScale<T> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            value: ::core::clone::Clone::clone(&self.value),
            scale: ::core::clone::Clone::clone(&self.scale),
        }
    }
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for WithScale<T> { }Copy, #[automatically_derived]
impl<T: ::core::default::Default> ::core::default::Default for WithScale<T> {
    #[inline]
    fn default() -> Self {
        Self {
            value: ::core::default::Default::default(),
            scale: ::core::default::Default::default(),
        }
    }
}Default)]
13pub(crate) struct WithScale<T> {
14    pub value: T,
15    pub scale: i64,
16}
17
18impl<T> WithScale<T>  {
19    /// Return new WithScale object with borrowed value and copied scale
20    pub fn as_ref(&self) -> WithScale<&T> {
21        let &WithScale { ref value, scale } = self;
22        WithScale { value, scale }
23    }
24}
25
26macro_rules! impl_is_zero_for {
27    ($t:ty) => {
28        impl WithScale<$t> {
29            pub fn is_zero(&self) -> bool {
30                self.value.is_zero()
31            }
32        }
33    }
34}
35
36impl WithScale<&BigUint> {
    pub fn is_zero(&self) -> bool { self.value.is_zero() }
}impl_is_zero_for!(&BigUint);
37
38impl<T: fmt::Debug> fmt::Debug for WithScale<T> {
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        f.write_fmt(format_args!("(scale={0} {1:?})", self.scale, self.value))write!(f, "(scale={} {:?})", self.scale, self.value)
41    }
42}
43
44impl<T> From<(T, i64)> for WithScale<T> {
45    fn from(pair: (T, i64)) -> Self {
46        Self { value: pair.0, scale: pair.1 }
47    }
48}
49
50impl<'a> From<WithScale<&'a BigInt>> for BigDecimalRef<'a> {
51    fn from(obj: WithScale<&'a BigInt>) -> Self {
52        Self {
53            scale: obj.scale,
54            sign: obj.value.sign(),
55            digits: obj.value.magnitude(),
56        }
57    }
58}
59
60impl<'a> From<WithScale<&'a BigUint>> for BigDecimalRef<'a> {
61    fn from(obj: WithScale<&'a BigUint>) -> Self {
62        Self {
63            scale: obj.scale,
64            sign: Sign::Plus,
65            digits: obj.value,
66        }
67    }
68}
69
70impl From<WithScale<BigUint>> for BigDecimal {
71    fn from(obj: WithScale<BigUint>) -> Self {
72        let WithScale { value, scale } = obj;
73        Self {
74            scale: scale,
75            int_val: value.into(),
76        }
77    }
78}
79
80impl<'a> From<BigDecimalRef<'a>> for WithScale<&'a BigUint> {
81    fn from(obj: BigDecimalRef<'a>) -> Self {
82        Self {
83            value: obj.digits,
84            scale: obj.scale,
85        }
86    }
87}
88
89impl<'a, T> From<&'a WithScale<T>> for WithScale<&'a T> {
90    fn from(obj: &'a WithScale<T>) -> Self {
91        let &WithScale { ref value, scale } = obj;
92        Self { scale, value }
93    }
94}
95
96impl WithScale<BigUint> {
97    pub fn addassign_scaled_biguint<'a, Rhs>(&mut self, rhs: Rhs)
98        where Rhs: Into<WithScale<&'a BigUint>>
99    {
100        addition::addassign_scaled_biguint(self, rhs.into());
101    }
102
103    pub fn mulassign_scaled_biguint<'a, Rhs>(&mut self, rhs: Rhs)
104        where Rhs: Into<WithScale<&'a BigUint>>
105    {
106        let rhs = rhs.into();
107        self.scale += rhs.scale;
108        self.value *= rhs.value;
109    }
110
111    pub fn count_int_digits(&self) -> i64 {
112        let total_digits = decimal::count_digits_biguint(&self.value);
113        total_digits as i64 - self.scale
114    }
115
116    pub fn bits(&self) -> u64 {
117        self.value.bits()
118    }
119}