substreams/
scalar.rs

1use std::ops::{
2    BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Rem, Shl, ShlAssign, Shr,
3    ShrAssign,
4};
5
6use num_bigint::{Sign, ToBigInt};
7use num_integer::Integer;
8use num_traits::{FromPrimitive, Pow, Signed};
9use {
10    bigdecimal::{One, ParseBigDecimalError, ToPrimitive, Zero},
11    num_bigint::{BigUint, ParseBigIntError, Sign as BigIntSign},
12    std::{
13        convert::{TryFrom, TryInto},
14        fmt::{self, Display, Formatter},
15        ops::{Add, Div, Mul, Neg, Sub},
16        str,
17        str::FromStr,
18    },
19    thiserror::Error,
20};
21
22// ---------- BigDecimal ---------- //
23#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
24pub struct BigDecimal(bigdecimal::BigDecimal);
25
26impl BigDecimal {
27    /// These are the limits of IEEE-754 decimal128, a format we may want to switch to.
28    ///
29    /// See <https://en.wikipedia.org/wiki/Decimal128_floating-point_format>
30    pub const MIN_EXP: i32 = -6143;
31    pub const MAX_EXP: i32 = 6144;
32    pub const MAX_SIGNIFICANT_DIGITS: i32 = 34;
33
34    pub fn new(digits: BigInt, exp: i64) -> Self {
35        // bigdecimal uses `scale` as the opposite of the power of ten, so negate `exp`.
36        Self::from(bigdecimal::BigDecimal::new(digits.0, -exp))
37    }
38
39    pub fn parse_bytes(bytes: &[u8]) -> Option<Self> {
40        bigdecimal::BigDecimal::parse_bytes(bytes, 10).map(Self)
41    }
42
43    pub fn zero() -> BigDecimal {
44        BigDecimal::from(0)
45    }
46
47    pub fn one() -> BigDecimal {
48        BigDecimal::from(1)
49    }
50
51    pub fn as_bigint_and_exponent(&self) -> (num_bigint::BigInt, i64) {
52        self.0.as_bigint_and_exponent()
53    }
54
55    pub fn digits(&self) -> u64 {
56        self.0.digits()
57    }
58
59    pub fn is_zero(&self) -> bool {
60        self.0.is_zero()
61    }
62
63    pub fn with_prec(&self, prec: u64) -> BigDecimal {
64        BigDecimal::from(self.0.with_prec(prec))
65    }
66
67    pub fn neg(&self) -> BigDecimal {
68        BigDecimal::from(self.0.clone().neg())
69    }
70
71    pub fn from_store_bytes(bytes: &[u8]) -> BigDecimal {
72        if bytes.len() == 0 {
73            return BigDecimal::zero();
74        }
75
76        let bytes_as_str = str::from_utf8(bytes.as_ref()).unwrap_or_else(|_| {
77            panic!(
78                "Invalid store UTF-8 bytes '{}'",
79                hex::encode(bytes.as_ref())
80            )
81        });
82
83        BigDecimal::from_str(bytes_as_str)
84            .unwrap_or_else(|_| panic!("Invalid store BigDecimal string '{}'", bytes_as_str))
85    }
86
87    pub fn divide_by_decimals(big_decimal_amount: BigDecimal, decimals: u64) -> BigDecimal {
88        // FIXME: Should we think about using a table of pre-made BigDecimal for a range of decimals between 0 -> 20?
89        big_decimal_amount.div(BigDecimal::new(BigInt::one(), decimals as i64))
90    }
91
92    pub fn absolute(&self) -> BigDecimal {
93        // TODO: implement as a a trit
94        BigDecimal::from(self.0.abs())
95    }
96
97    pub fn to_bigint(&self) -> BigInt {
98        BigInt(
99            self.0
100                .to_bigint()
101                .unwrap_or_else(|| panic!("Unable to convert BigDecimal '{}' into BigInt", self)),
102        )
103    }
104}
105
106impl AsRef<BigDecimal> for BigDecimal {
107    fn as_ref(&self) -> &BigDecimal {
108        &self
109    }
110}
111
112impl ToPrimitive for BigDecimal {
113    fn to_i64(&self) -> Option<i64> {
114        self.0.to_i64()
115    }
116    fn to_u64(&self) -> Option<u64> {
117        self.0.to_u64()
118    }
119}
120
121impl Display for BigDecimal {
122    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
123        self.0.fmt(f)
124    }
125}
126
127impl Default for BigDecimal {
128    fn default() -> Self {
129        Self::zero()
130    }
131}
132
133impl fmt::Debug for BigDecimal {
134    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135        write!(f, "BigDecimal({})", self.0)
136    }
137}
138
139impl FromStr for BigDecimal {
140    type Err = <bigdecimal::BigDecimal as FromStr>::Err;
141
142    fn from_str(s: &str) -> Result<BigDecimal, Self::Err> {
143        Ok(Self::from(bigdecimal::BigDecimal::from_str(s)?))
144    }
145}
146
147impl TryFrom<String> for BigDecimal {
148    type Error = ParseBigDecimalError;
149
150    fn try_from(value: String) -> Result<Self, Self::Error> {
151        BigDecimal::try_from(value.as_str())
152    }
153}
154
155impl TryFrom<&String> for BigDecimal {
156    type Error = ParseBigDecimalError;
157
158    fn try_from(value: &String) -> Result<Self, Self::Error> {
159        BigDecimal::try_from(value.as_str())
160    }
161}
162
163impl TryFrom<&str> for BigDecimal {
164    type Error = ParseBigDecimalError;
165
166    fn try_from(value: &str) -> Result<Self, Self::Error> {
167        bigdecimal::BigDecimal::from_str(value).map(|bd| BigDecimal(bd))
168    }
169}
170
171impl From<i32> for BigDecimal {
172    fn from(n: i32) -> Self {
173        Self::from(bigdecimal::BigDecimal::from(n))
174    }
175}
176
177impl From<u32> for BigDecimal {
178    fn from(n: u32) -> Self {
179        Self::from(bigdecimal::BigDecimal::from(n))
180    }
181}
182
183impl From<i64> for BigDecimal {
184    fn from(n: i64) -> Self {
185        Self::from(bigdecimal::BigDecimal::from(n))
186    }
187}
188
189impl From<u64> for BigDecimal {
190    fn from(n: u64) -> Self {
191        Self::from(bigdecimal::BigDecimal::from(n))
192    }
193}
194
195impl From<usize> for BigDecimal {
196    fn from(n: usize) -> Self {
197        match bigdecimal::BigDecimal::from_usize(n) {
198            None => {
199                panic!("creating big decimal from invalid usize value {}", n)
200            }
201            Some(bd) => BigDecimal(bd),
202        }
203    }
204}
205
206impl From<BigInt> for BigDecimal {
207    fn from(n: BigInt) -> Self {
208        Self::from(bigdecimal::BigDecimal::from(n.0))
209    }
210}
211
212impl From<BigUint> for BigDecimal {
213    fn from(val: BigUint) -> Self {
214        BigInt(num_bigint::BigInt::from(val)).into()
215    }
216}
217
218impl From<bigdecimal::BigDecimal> for BigDecimal {
219    fn from(big_decimal: bigdecimal::BigDecimal) -> Self {
220        BigDecimal(big_decimal)
221    }
222}
223
224impl From<&bigdecimal::BigDecimal> for BigDecimal {
225    fn from(big_decimal: &bigdecimal::BigDecimal) -> Self {
226        BigDecimal(big_decimal.clone())
227    }
228}
229
230impl TryFrom<f32> for BigDecimal {
231    type Error = ParseBigDecimalError;
232
233    #[inline]
234    fn try_from(n: f32) -> Result<Self, Self::Error> {
235        BigDecimal::from_str(&format!(
236            "{:.PRECISION$e}",
237            n,
238            PRECISION = ::std::f32::DIGITS as usize
239        ))
240    }
241}
242
243impl TryFrom<f64> for BigDecimal {
244    type Error = ParseBigDecimalError;
245
246    #[inline]
247    fn try_from(n: f64) -> Result<Self, Self::Error> {
248        BigDecimal::from_str(&format!(
249            "{:.PRECISION$e}",
250            n,
251            PRECISION = ::std::f64::DIGITS as usize
252        ))
253    }
254}
255
256impl Into<String> for &BigDecimal {
257    fn into(self) -> String {
258        self.to_string()
259    }
260}
261
262impl Into<String> for BigDecimal {
263    fn into(self) -> String {
264        self.to_string()
265    }
266}
267
268impl Into<bigdecimal::BigDecimal> for BigDecimal {
269    fn into(self) -> bigdecimal::BigDecimal {
270        self.0
271    }
272}
273
274impl<T> Add<T> for BigDecimal
275where
276    T: Into<BigDecimal>,
277{
278    type Output = BigDecimal;
279
280    fn add(self, other: T) -> BigDecimal {
281        BigDecimal(self.0 + other.into().0)
282    }
283}
284
285impl<T> Sub<T> for BigDecimal
286where
287    T: Into<BigDecimal>,
288{
289    type Output = BigDecimal;
290
291    fn sub(self, other: T) -> BigDecimal {
292        BigDecimal(self.0 - other.into().0)
293    }
294}
295
296impl<T> Mul<T> for BigDecimal
297where
298    T: Into<BigDecimal>,
299{
300    type Output = BigDecimal;
301
302    fn mul(self, rhs: T) -> BigDecimal {
303        BigDecimal(self.0 * rhs.into().0)
304    }
305}
306
307impl<T> Div<T> for BigDecimal
308where
309    T: Into<BigDecimal>,
310{
311    type Output = BigDecimal;
312
313    fn div(self, rhs: T) -> BigDecimal {
314        let rhs = rhs.into();
315        if rhs.is_zero() {
316            panic!("attempt to divide by zero");
317        }
318
319        BigDecimal(self.0 / rhs.0)
320    }
321}
322
323impl Div<&BigDecimal> for BigDecimal {
324    type Output = BigDecimal;
325
326    fn div(self, other: &BigDecimal) -> BigDecimal {
327        if other.is_zero() {
328            panic!("Cannot divide by zero-valued `BigDecimal`!")
329        }
330
331        Self::from(self.0.div(&other.0))
332    }
333}
334
335// ---------- BigInt ---------- //
336#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
337pub struct BigInt(num_bigint::BigInt);
338
339#[derive(Error, Debug)]
340pub enum BigIntOutOfRangeError {
341    #[error("Cannot convert negative BigInt into type")]
342    Negative,
343    #[error("BigInt value is too large for type")]
344    Overflow,
345}
346
347impl fmt::Debug for BigInt {
348    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
349        write!(f, "BigInt({})", self)
350    }
351}
352
353impl Display for BigInt {
354    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
355        self.0.fmt(f)
356    }
357}
358
359impl AsRef<BigInt> for BigInt {
360    fn as_ref(&self) -> &BigInt {
361        &self
362    }
363}
364
365impl BigInt {
366    pub fn new(sign: Sign, digits: Vec<u32>) -> BigInt {
367        return BigInt(num_bigint::BigInt::new(sign, digits));
368    }
369
370    pub fn zero() -> BigInt {
371        BigInt::from(0)
372    }
373
374    pub fn one() -> BigInt {
375        BigInt::from(1)
376    }
377
378    pub fn from_unsigned_bytes_be(bytes: &[u8]) -> Self {
379        BigInt(num_bigint::BigInt::from_bytes_be(
380            num_bigint::Sign::Plus,
381            bytes,
382        ))
383    }
384
385    pub fn from_unsigned_bytes_le(bytes: &[u8]) -> Self {
386        BigInt(num_bigint::BigInt::from_bytes_le(
387            num_bigint::Sign::Plus,
388            bytes,
389        ))
390    }
391
392    pub fn from_signed_bytes_le(bytes: &[u8]) -> Self {
393        BigInt(num_bigint::BigInt::from_signed_bytes_le(bytes))
394    }
395
396    pub fn from_signed_bytes_be(bytes: &[u8]) -> Self {
397        BigInt(num_bigint::BigInt::from_signed_bytes_be(bytes))
398    }
399
400    pub fn from_bytes_le(sign: BigIntSign, bytes: &[u8]) -> Self {
401        BigInt(num_bigint::BigInt::from_bytes_le(sign, bytes))
402    }
403
404    pub fn to_bytes_le(&self) -> (BigIntSign, Vec<u8>) {
405        self.0.to_bytes_le()
406    }
407
408    pub fn to_bytes_be(&self) -> (BigIntSign, Vec<u8>) {
409        self.0.to_bytes_be()
410    }
411
412    pub fn to_signed_bytes_le(&self) -> Vec<u8> {
413        self.0.to_signed_bytes_le()
414    }
415
416    pub fn to_signed_bytes_be(&self) -> Vec<u8> {
417        self.0.to_signed_bytes_be()
418    }
419
420    pub fn to_u64(&self) -> u64 {
421        self.0
422            .to_u64()
423            .unwrap_or_else(|| panic!("BigInt '{}' is too large to fit into u64", self))
424    }
425
426    pub fn to_i32(&self) -> i32 {
427        self.0
428            .to_i32()
429            .unwrap_or_else(|| panic!("BigInt '{}' is too large to fit into u32", self))
430    }
431
432    pub fn pow(self, exponent: u32) -> Self {
433        BigInt(self.0.pow(exponent))
434    }
435
436    pub fn bits(&self) -> usize {
437        self.0.bits() as usize
438    }
439
440    pub fn is_zero(&self) -> bool {
441        self.0.is_zero()
442    }
443
444    pub fn is_one(&self) -> bool {
445        self.0.is_one()
446    }
447
448    pub fn neg(&self) -> BigInt {
449        BigInt::from(self.0.clone().neg())
450    }
451
452    pub fn from_store_bytes(bytes: &[u8]) -> BigInt {
453        let bytes = bytes.as_ref();
454
455        if bytes.len() == 0 {
456            return BigInt::zero();
457        }
458
459        let bytes_as_str = str::from_utf8(bytes)
460            .unwrap_or_else(|_| panic!("Invalid store UTF-8 bytes '{}'", hex::encode(bytes)));
461
462        BigInt::from_str(bytes_as_str)
463            .unwrap_or_else(|_| panic!("Invalid store BigInt string '{}'", bytes_as_str))
464    }
465
466    pub fn to_decimal(&self, decimals: u64) -> BigDecimal {
467        // FIXME: Should we think about using a table of pre-made BigDecimal for a range of decimals between 0 -> 20?
468        let big_decimal_amount: BigDecimal = self.into();
469        return big_decimal_amount.div(BigDecimal::new(BigInt::one(), decimals as i64));
470    }
471
472    pub fn absolute(&self) -> BigInt {
473        BigInt::from(self.0.abs())
474    }
475
476    pub fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
477        let (quotient, remainder) = num_bigint::BigInt::div_rem(&self.0, &other.0);
478        return (BigInt(quotient), BigInt(remainder));
479    }
480}
481
482impl Default for BigInt {
483    fn default() -> Self {
484        BigInt::zero()
485    }
486}
487
488impl FromStr for BigInt {
489    type Err = <num_bigint::BigInt as FromStr>::Err;
490
491    fn from_str(s: &str) -> Result<BigInt, Self::Err> {
492        num_bigint::BigInt::from_str(s).map(BigInt)
493    }
494}
495
496impl From<u32> for BigInt {
497    fn from(i: u32) -> BigInt {
498        BigInt(i.into())
499    }
500}
501
502impl From<i32> for BigInt {
503    fn from(i: i32) -> BigInt {
504        BigInt(i.into())
505    }
506}
507
508impl From<u64> for BigInt {
509    fn from(i: u64) -> BigInt {
510        BigInt(i.into())
511    }
512}
513
514impl From<i64> for BigInt {
515    fn from(i: i64) -> BigInt {
516        BigInt(i.into())
517    }
518}
519
520impl From<usize> for BigInt {
521    fn from(i: usize) -> BigInt {
522        BigInt(i.into())
523    }
524}
525
526impl From<isize> for BigInt {
527    fn from(i: isize) -> BigInt {
528        BigInt(i.into())
529    }
530}
531
532impl TryFrom<String> for BigInt {
533    type Error = ParseBigIntError;
534
535    fn try_from(value: String) -> Result<Self, Self::Error> {
536        BigInt::from_str(value.as_str())
537    }
538}
539
540impl TryFrom<&String> for BigInt {
541    type Error = ParseBigIntError;
542
543    fn try_from(value: &String) -> Result<Self, Self::Error> {
544        BigInt::from_str(value.as_str())
545    }
546}
547
548impl From<num_bigint::BigInt> for BigInt {
549    fn from(big_int: num_bigint::BigInt) -> BigInt {
550        BigInt(big_int)
551    }
552}
553
554impl Into<num_bigint::BigInt> for BigInt {
555    fn into(self) -> num_bigint::BigInt {
556        self.0
557    }
558}
559
560impl TryFrom<BigInt> for u64 {
561    type Error = BigIntOutOfRangeError;
562    fn try_from(value: BigInt) -> Result<u64, BigIntOutOfRangeError> {
563        (&value).try_into()
564    }
565}
566
567impl<'a> TryFrom<&'a BigInt> for u64 {
568    type Error = BigIntOutOfRangeError;
569    fn try_from(value: &'a BigInt) -> Result<u64, BigIntOutOfRangeError> {
570        let (sign, bytes) = value.to_bytes_le();
571
572        if sign == num_bigint::Sign::Minus {
573            return Err(BigIntOutOfRangeError::Negative);
574        }
575
576        if bytes.len() > 8 {
577            return Err(BigIntOutOfRangeError::Overflow);
578        }
579
580        // Replace this with u64::from_le_bytes when stabilized
581        let mut n = 0u64;
582        let mut shift_dist = 0;
583        for b in bytes {
584            n |= (b as u64) << shift_dist;
585            shift_dist += 8;
586        }
587        Ok(n)
588    }
589}
590
591impl Into<u32> for BigInt {
592    fn into(self) -> u32 {
593        self.0
594            .to_u32()
595            .unwrap_or_else(|| panic!("BigInt '{}' is too large to fit into u32", self))
596    }
597}
598
599impl Into<i32> for BigInt {
600    fn into(self) -> i32 {
601        self.0
602            .to_i32()
603            .unwrap_or_else(|| panic!("BigInt '{}' is too large to fit into i32", self))
604    }
605}
606
607impl Into<String> for BigInt {
608    fn into(self) -> String {
609        self.to_string()
610    }
611}
612
613impl Into<String> for &BigInt {
614    fn into(self) -> String {
615        self.to_string()
616    }
617}
618
619impl Into<BigDecimal> for &BigInt {
620    fn into(self) -> BigDecimal {
621        BigDecimal(bigdecimal::BigDecimal::from(self.0.clone()))
622    }
623}
624
625impl Add<BigDecimal> for BigInt {
626    type Output = BigDecimal;
627
628    fn add(self, other: BigDecimal) -> BigDecimal {
629        let lhs: BigDecimal = self.into();
630        lhs.add(other)
631    }
632}
633
634macro_rules! impl_add_floats_bigint {
635    ($($t:ty),*) => {
636        $(
637            impl Add<$t> for BigInt
638            {
639                type Output = BigDecimal;
640
641                fn add(self, other: $t) -> BigDecimal {
642                    let rhs: BigDecimal = other.try_into().unwrap_or_else(|_| panic!("Cannot convert '{}' to BigDecimal", other));
643                    self.add(rhs)
644                }
645            }
646        )*
647    }
648}
649impl_add_floats_bigint!(f32, f64);
650
651macro_rules! impl_add_bigint_float {
652    ($($t:ty),*) => {
653        $(
654            impl Add<BigInt> for $t
655            {
656                type Output = BigDecimal;
657
658                fn add(self, other: BigInt) -> BigDecimal {
659                    let lhs: BigDecimal = match self.try_into() {
660                        Ok(v) => v,
661                        Err(_) => panic!("Cannot convert {} to BigDecimal", self)
662                    };
663                    let rhs: BigDecimal = other.into();
664                    lhs.add(rhs)
665                }
666            }
667        )*
668    }
669}
670impl_add_bigint_float!(f32, f64);
671
672impl Sub<BigDecimal> for BigInt {
673    type Output = BigDecimal;
674
675    fn sub(self, other: BigDecimal) -> BigDecimal {
676        let lhs: BigDecimal = self.into();
677        lhs.sub(other)
678    }
679}
680
681macro_rules! impl_sub_floats_bigint {
682    ($($t:ty),*) => {
683        $(
684            impl Sub<$t> for BigInt
685            {
686                type Output = BigDecimal;
687
688                fn sub(self, other: $t) -> BigDecimal {
689                    let rhs: BigDecimal = other.try_into().unwrap_or_else(|_| panic!("Cannot convert '{}' to BigDecimal", other));
690                    self.sub(rhs)
691                }
692            }
693        )*
694    }
695}
696impl_sub_floats_bigint!(f32, f64);
697
698macro_rules! impl_sub_bigint_float {
699    ($($t:ty),*) => {
700        $(
701            impl Sub<BigInt> for $t
702            {
703                type Output = BigDecimal;
704
705                fn sub(self, other: BigInt) -> BigDecimal {
706                    let lhs: BigDecimal = match self.try_into() {
707                        Ok(v) => v,
708                        Err(_) => panic!("Cannot convert {} to BigDecimal", self)
709                    };
710                    let rhs: BigDecimal = other.into();
711                    lhs.sub(rhs)
712                }
713            }
714        )*
715    }
716}
717impl_sub_bigint_float!(f32, f64);
718
719impl Mul<BigDecimal> for BigInt {
720    type Output = BigDecimal;
721
722    fn mul(self, other: BigDecimal) -> BigDecimal {
723        let lhs: BigDecimal = self.into();
724        lhs.mul(other)
725    }
726}
727
728macro_rules! impl_mul_floats_bigint {
729    ($($t:ty),*) => {
730        $(
731            impl Mul<$t> for BigInt
732            {
733                type Output = BigDecimal;
734
735                fn mul(self, other: $t) -> BigDecimal {
736                    let rhs: BigDecimal = other.try_into().unwrap_or_else(|_| panic!("Cannot convert '{}' to BigDecimal", other));
737                    self.mul(rhs)
738                }
739            }
740        )*
741    }
742}
743impl_mul_floats_bigint!(f32, f64);
744
745macro_rules! impl_mul_bigint_float {
746    ($($t:ty),*) => {
747        $(
748            impl Mul<BigInt> for $t
749            {
750                type Output = BigDecimal;
751
752                fn mul(self, other: BigInt) -> BigDecimal {
753                    let lhs: BigDecimal = match self.try_into() {
754                        Ok(v) => v,
755                        Err(_) => panic!("Cannot convert {} to BigDecimal", self)
756                    };
757                    let rhs: BigDecimal = other.into();
758                    lhs.mul(rhs)
759                }
760            }
761        )*
762    }
763}
764impl_mul_bigint_float!(f32, f64);
765
766impl Div<BigDecimal> for BigInt {
767    type Output = BigDecimal;
768
769    fn div(self, other: BigDecimal) -> BigDecimal {
770        if other.is_zero() {
771            panic!("Cannot divide by zero-valued `BigDecimal`!")
772        }
773        let lhs: BigDecimal = self.into();
774        lhs.div(other)
775    }
776}
777
778macro_rules! impl_div_floats_bigint {
779    ($($t:ty),*) => {
780        $(
781            impl Div<$t> for BigInt
782            {
783                type Output = BigDecimal;
784
785                fn div(self, other: $t) -> BigDecimal {
786                    if other.is_zero() {
787                        panic!("Cannot divide by zero-valued `BigDecimal`!")
788                    }
789                    let rhs: BigDecimal = other.try_into().unwrap_or_else(|_| panic!("Cannot convert '{}' to BigDecimal", other));
790                    self.div(rhs)
791                }
792            }
793        )*
794    }
795}
796impl_div_floats_bigint!(f32, f64);
797
798macro_rules! impl_div_bigint_float {
799    ($($t:ty),*) => {
800        $(
801            impl Div<BigInt> for $t
802            {
803                type Output = BigDecimal;
804
805                fn div(self, other: BigInt) -> BigDecimal {
806                    let lhs: BigDecimal = match self.try_into() {
807                        Ok(v) => v,
808                        Err(_) => panic!("Cannot convert {} to BigDecimal", self)
809                    };
810
811                    let rhs: BigDecimal = other.into();
812                    if rhs.is_zero() {
813                        panic!("Cannot divide by zero-valued `BigDecimal`!")
814                    }
815                    lhs.div(rhs)
816                }
817            }
818        )*
819    }
820}
821impl_div_bigint_float!(f32, f64);
822
823/// The macro reads as follow
824///
825/// ```md
826///     impl <Trait> for (<prefix> <lhs>, <prefix> <rhs>) fn <method>
827/// ```
828///
829/// When using this macros, you think in term of binary operation, where the <lhs> operand is the
830/// type on which the trait is implemented, and the <rhs> operand is the type of the argument.
831///
832/// So the above example can be read as
833///
834/// ```md
835///     impl Trait<rhs> for lhs {
836///         $method(self, rhs: $rhs) -> BigInt {
837///             BigInt { 0: /* code */ }
838///         }
839///     }
840/// ```
841///
842/// The `ref` prefix means that the right operand is a reference to the type, you must still
843/// provide the `&`, the `ref` keyword is used in the macro below to decide how the arguments
844/// will actually be sent to the proxy implementation.
845///
846/// The `primitive` prefix means that type is a primitive type, and that the trait is implemented
847/// using primitive calling convention.
848///
849/// The `primitive into` prefix means that type is a primitive type but the underlying `num_big::BigInt`
850/// do not implement natively primitive type and that a conversion `num_big::BitInt::from(<primitive value>).
851macro_rules! forward_val_val_binop {
852    (impl $imp:ident for ($lhs:ty, $rhs:ty) fn $method:ident) => {
853        impl $imp<$rhs> for $lhs {
854            type Output = BigInt;
855
856            #[inline]
857            fn $method(self, rhs: $rhs) -> BigInt {
858                BigInt {
859                    0: $imp::$method(self.0, rhs.0),
860                }
861            }
862        }
863    };
864
865    (impl $imp:ident for (ref $lhs:ty, $rhs:ty) fn $method:ident) => {
866        impl $imp<$rhs> for $lhs {
867            type Output = BigInt;
868
869            #[inline]
870            fn $method(self, rhs: $rhs) -> BigInt {
871                BigInt {
872                    0: $imp::$method(&self.0, rhs.0),
873                }
874            }
875        }
876    };
877
878    (impl $imp:ident for ($lhs:ty, ref $rhs:ty) fn $method:ident) => {
879        impl $imp<$rhs> for $lhs {
880            type Output = BigInt;
881
882            #[inline]
883            fn $method(self, rhs: $rhs) -> BigInt {
884                BigInt {
885                    0: $imp::$method(self.0, &rhs.0),
886                }
887            }
888        }
889    };
890
891    (impl $imp:ident for (ref $lhs:ty, ref $rhs:ty) fn $method:ident) => {
892        impl $imp<$rhs> for $lhs {
893            type Output = BigInt;
894
895            #[inline]
896            fn $method(self, rhs: $rhs) -> BigInt {
897                BigInt {
898                    0: $imp::$method(&self.0, &rhs.0),
899                }
900            }
901        }
902    };
903
904    (impl $imp:ident for ($lhs:ty, primitive $($rhs:ty);+) fn $method:ident) => {
905        $(
906            impl $imp<$rhs> for $lhs {
907                type Output = BigInt;
908
909                #[inline]
910                fn $method(self, rhs: $rhs) -> BigInt {
911                    BigInt {
912                        0: $imp::$method(&self.0, rhs),
913                    }
914                }
915            }
916        )*
917    };
918
919    (impl $imp:ident for (primitive $($lhs:ty);+, $rhs:ty) fn $method:ident) => {
920        $(
921            impl $imp<$rhs> for $lhs {
922                type Output = BigInt;
923
924                #[inline]
925                fn $method(self, rhs: $rhs) -> BigInt {
926                    BigInt {
927                        0: $imp::$method(self, rhs.0),
928                    }
929                }
930            }
931        )*
932    };
933
934    (impl $imp:ident for (into $($lhs:ty);+, $rhs:ty) fn $method:ident) => {
935        $(
936            impl $imp<$rhs> for $lhs {
937                type Output = BigInt;
938
939                #[inline]
940                fn $method(self, rhs: $rhs) -> BigInt {
941                    BigInt {
942                        0: $imp::$method(Into::<num_bigint::BigInt>::into(self), rhs.0),
943                    }
944                }
945            }
946        )*
947    };
948
949    (impl $imp:ident for ($lhs:ty, into $($rhs:ty);+) fn $method:ident) => {
950        $(
951            impl $imp<$rhs> for $lhs {
952                type Output = BigInt;
953
954                #[inline]
955                fn $method(self, rhs: $rhs) -> BigInt {
956                    BigInt {
957                        0: $imp::$method(&self.0, Into::<num_bigint::BigInt>::into(rhs)),
958                    }
959                }
960            }
961        )*
962    };
963}
964
965// See forward_val_val_binop for details, same thing but for `XXXAssign` traits
966macro_rules! forward_val_val_binop_assign {
967    (impl mut $imp:ident for ($lhs:ty, $rhs:ty) fn $method:ident) => {
968        impl $imp<$rhs> for $lhs {
969            #[inline]
970            fn $method(&mut self, rhs: $rhs) {
971                $imp::$method(&mut self.0, rhs.0)
972            }
973        }
974    };
975
976    (impl mut $imp:ident for ($lhs:ty, ref $rhs:ty) fn $method:ident) => {
977        impl $imp<$rhs> for $lhs {
978            #[inline]
979            fn $method(&mut self, rhs: $rhs) {
980                $imp::$method(&mut self.0, &rhs.0)
981            }
982        }
983    };
984
985    (impl mut $imp:ident for ($lhs:ty, primitive $($rhs:ty);+) fn $method:ident) => {
986        $(
987            impl $imp<$rhs> for $lhs {
988                #[inline]
989                fn $method(&mut self, rhs: $rhs) {
990                    $imp::$method(&mut self.0, rhs)
991                }
992            }
993        )*
994    };
995
996    (impl mut $imp:ident for ($lhs:ty, into $($rhs:ty);+) fn $method:ident) => {
997        $(
998            impl $imp<$rhs> for $lhs {
999                #[inline]
1000                fn $method(&mut self, rhs: $rhs) {
1001                    $imp::$method(&mut self.0, Into::<num_bigint::BigInt>::into(rhs))
1002                }
1003            }
1004        )*
1005    };
1006}
1007
1008macro_rules! forward_artithmetic_binop {
1009    (impl $impl:ident fn $method:ident) => {
1010        forward_val_val_binop!(impl $impl for (BigInt, BigInt) fn $method);
1011        forward_val_val_binop!(impl $impl for (ref &BigInt, BigInt) fn $method);
1012        forward_val_val_binop!(impl $impl for (BigInt, ref &BigInt) fn $method);
1013        forward_val_val_binop!(impl $impl for (ref &BigInt, ref &BigInt) fn $method);
1014        forward_val_val_binop!(impl $impl for (BigInt, primitive i8; u8; i16; u16; u32; i32; u64; i64; usize; isize) fn $method);
1015        forward_val_val_binop!(impl $impl for (primitive i8; u8; i16; u16; u32; i32; u64; i64; usize; isize, BigInt) fn $method);
1016    };
1017}
1018
1019macro_rules! forward_logical_binop {
1020    (impl $impl:ident fn $method:ident) => {
1021        forward_val_val_binop!(impl $impl for (BigInt, BigInt) fn $method);
1022        forward_val_val_binop!(impl $impl for (into i8; u8; i16; u16; u32; i32; u64; i64; usize; isize, BigInt) fn $method);
1023        forward_val_val_binop!(impl $impl for (BigInt, into i8; u8; i16; u16; u32; i32; u64; i64; usize; u128; i128; isize) fn $method);
1024        forward_val_val_binop!(impl $impl for (ref &BigInt, BigInt) fn $method);
1025        forward_val_val_binop!(impl $impl for (BigInt, ref &BigInt) fn $method);
1026        forward_val_val_binop!(impl $impl for (ref &BigInt, ref &BigInt) fn $method);
1027    };
1028}
1029
1030macro_rules! forward_logical_binop_assign {
1031    (impl $impl:ident fn $method:ident) => {
1032        forward_val_val_binop_assign!(impl mut $impl for (BigInt, BigInt) fn $method);
1033        forward_val_val_binop_assign!(impl mut $impl for (BigInt, ref &BigInt) fn $method);
1034        forward_val_val_binop_assign!(impl mut $impl for (BigInt, into u8; i8; u16; i16; u32; i32; u64; i64; u128; i128; usize; isize) fn $method);
1035    };
1036}
1037
1038forward_artithmetic_binop!(impl Add fn add);
1039forward_artithmetic_binop!(impl Div fn div);
1040forward_artithmetic_binop!(impl Mul fn mul);
1041forward_val_val_binop!(impl Pow for (BigInt, primitive u8; u16; u32; u64; u128; usize) fn pow);
1042forward_artithmetic_binop!(impl Rem fn rem);
1043forward_artithmetic_binop!(impl Sub fn sub);
1044
1045forward_logical_binop!(impl BitAnd fn bitand);
1046forward_logical_binop!(impl BitOr fn bitor);
1047forward_logical_binop!(impl BitXor fn bitxor);
1048forward_val_val_binop!(impl Shl for (BigInt, primitive u8; i8; u16; i16; u32; i32; u64; i64; u128; i128; usize; isize) fn shl);
1049forward_val_val_binop!(impl Shr for (BigInt, primitive u8; i8; u16; i16; u32; i32; u64; i64; u128; i128; usize; isize) fn shr);
1050
1051forward_logical_binop_assign!(impl BitAndAssign fn bitand_assign);
1052forward_logical_binop_assign!(impl BitOrAssign fn bitor_assign);
1053forward_logical_binop_assign!(impl BitXorAssign fn bitxor_assign);
1054forward_val_val_binop_assign!(impl mut ShlAssign for (BigInt, primitive u8; i8; u16; i16; u32; i32; u64; i64; u128; i128; usize; isize) fn shl_assign);
1055forward_val_val_binop_assign!(impl mut ShrAssign for (BigInt, primitive u8; i8; u16; i16; u32; i32; u64; i64; u128; i128; usize; isize) fn shr_assign);
1056
1057#[cfg(test)]
1058mod tests {
1059    use super::BigDecimal;
1060    use super::BigInt;
1061    use std::convert::TryFrom;
1062
1063    fn big_decimal(input: f64) -> BigDecimal {
1064        BigDecimal::try_from(input).unwrap()
1065    }
1066
1067    fn big_uint(input: u64) -> BigInt {
1068        BigInt::try_from(input).unwrap()
1069    }
1070
1071    fn big_int(input: i64) -> BigInt {
1072        BigInt::try_from(input).unwrap()
1073    }
1074
1075    #[test]
1076    fn bigint_op_int() {
1077        assert_eq!(big_int(1) + 1 as i32, big_int(2));
1078        assert_eq!(big_int(1) + 1 as i64, big_int(2));
1079        assert_eq!(big_int(1) + 1 as u32, big_int(2));
1080        assert_eq!(big_int(1) + 1 as u64, big_int(2));
1081        assert_eq!(big_int(1) + 1 as isize, big_int(2));
1082        assert_eq!(big_int(1) + 1 as usize, big_int(2));
1083        assert_eq!(big_int(1) + 1, big_int(2));
1084        assert_eq!(big_int(1) - 1 as i32, big_int(0));
1085        assert_eq!(big_int(1) - 1 as i64, big_int(0));
1086        assert_eq!(big_int(1) - 1 as u32, big_int(0));
1087        assert_eq!(big_int(1) - 1 as u64, big_int(0));
1088        assert_eq!(big_int(1) - 1 as isize, big_int(0));
1089        assert_eq!(big_int(1) - 1 as usize, big_int(0));
1090        assert_eq!(big_int(1) - 1, big_int(0));
1091        assert_eq!(big_int(2) * 2 as i32, big_int(4));
1092        assert_eq!(big_int(2) * 2 as i64, big_int(4));
1093        assert_eq!(big_int(2) * 2 as u32, big_int(4));
1094        assert_eq!(big_int(2) * 2 as u64, big_int(4));
1095        assert_eq!(big_int(2) * 2 as isize, big_int(4));
1096        assert_eq!(big_int(2) * 2 as usize, big_int(4));
1097        assert_eq!(big_int(2) * 2, big_int(4));
1098        assert_eq!(big_int(4) / 2 as i32, big_int(2));
1099        assert_eq!(big_int(4) / 2 as i64, big_int(2));
1100        assert_eq!(big_int(4) / 2 as u32, big_int(2));
1101        assert_eq!(big_int(4) / 2 as u64, big_int(2));
1102        assert_eq!(big_int(4) / 2 as isize, big_int(2));
1103        assert_eq!(big_int(4) / 2 as usize, big_int(2));
1104        assert_eq!(big_int(4) / 2, big_int(2));
1105        assert_eq!(big_int(3) / 2 as i32, big_int(1));
1106        assert_eq!(big_int(3) / 2 as i64, big_int(1));
1107        assert_eq!(big_int(3) / 2 as u32, big_int(1));
1108        assert_eq!(big_int(3) / 2 as u64, big_int(1));
1109        assert_eq!(big_int(3) / 2 as isize, big_int(1));
1110        assert_eq!(big_int(3) / 2 as usize, big_int(1));
1111        assert_eq!(big_int(3) / 2, big_int(1));
1112    }
1113
1114    #[test]
1115    fn big_uint_minus_int_is_signed() {
1116        assert_eq!(big_uint(1) - 2 as i32, big_int(-1));
1117        assert_eq!(big_uint(1) - 2 as i64, big_int(-1));
1118        assert_eq!(big_uint(1) - 2 as u32, big_int(-1));
1119        assert_eq!(big_uint(1) - 2 as u64, big_int(-1));
1120        assert_eq!(big_uint(1) - 2 as isize, big_int(-1));
1121        assert_eq!(big_uint(1) - 2 as usize, big_int(-1));
1122        assert_eq!(big_uint(1) - 2, big_int(-1));
1123    }
1124
1125    //
1126    #[test]
1127    fn int_op_bigint() {
1128        // Minus
1129        assert_eq!(big_int(1) - big_int(1), big_int(0));
1130        assert_eq!(&big_int(1) - big_int(1), big_int(0));
1131        assert_eq!(big_int(1) - &big_int(1), big_int(0));
1132        assert_eq!(&big_int(1) - &big_int(1), big_int(0));
1133
1134        // Add
1135        assert_eq!(big_int(1) + big_int(1), big_int(2));
1136        assert_eq!(&big_int(1) + big_int(1), big_int(2));
1137        assert_eq!(big_int(1) + &big_int(1), big_int(2));
1138        assert_eq!(&big_int(1) + &big_int(1), big_int(2));
1139
1140        // BitAnd
1141        assert_eq!(1 as i32 & big_int(1), big_int(1));
1142        assert_eq!(1 as i64 & big_int(1), big_int(1));
1143        assert_eq!(1 as u32 & big_int(1), big_int(1));
1144        assert_eq!(1 as u64 & big_int(1), big_int(1));
1145        assert_eq!(1 as isize & big_int(1), big_int(1));
1146        assert_eq!(1 as usize & big_int(1), big_int(1));
1147        assert_eq!(big_int(1) & 1 as i32, big_int(1));
1148        assert_eq!(big_int(1) & 1 as i64, big_int(1));
1149        assert_eq!(big_int(1) & 1 as u32, big_int(1));
1150        assert_eq!(big_int(1) & 1 as u64, big_int(1));
1151        assert_eq!(big_int(1) & 1 as isize, big_int(1));
1152        assert_eq!(big_int(1) & 1 as usize, big_int(1));
1153        assert_eq!(big_int(1) & big_int(1), big_int(1));
1154        assert_eq!(big_int(1) & &big_int(1), big_int(1));
1155        assert_eq!(&big_int(1) & big_int(1), big_int(1));
1156        assert_eq!(&big_int(1) & &big_int(1), big_int(1));
1157
1158        // BitOr
1159        assert_eq!(1 as i32 | big_int(1), big_int(1));
1160        assert_eq!(1 as i64 | big_int(1), big_int(1));
1161        assert_eq!(1 as u32 | big_int(1), big_int(1));
1162        assert_eq!(1 as u64 | big_int(1), big_int(1));
1163        assert_eq!(1 as isize | big_int(1), big_int(1));
1164        assert_eq!(1 as usize | big_int(1), big_int(1));
1165        assert_eq!(big_int(1) | 1 as i32, big_int(1));
1166        assert_eq!(big_int(1) | 1 as i64, big_int(1));
1167        assert_eq!(big_int(1) | 1 as u32, big_int(1));
1168        assert_eq!(big_int(1) | 1 as u64, big_int(1));
1169        assert_eq!(big_int(1) | 1 as isize, big_int(1));
1170        assert_eq!(big_int(1) | 1 as usize, big_int(1));
1171        assert_eq!(big_int(1) | big_int(1), big_int(1));
1172        assert_eq!(big_int(1) | &big_int(1), big_int(1));
1173        assert_eq!(&big_int(1) | big_int(1), big_int(1));
1174        assert_eq!(&big_int(1) | &big_int(1), big_int(1));
1175
1176        // BitXor
1177        assert_eq!(1 as i32 ^ big_int(1), big_int(0));
1178        assert_eq!(1 as i64 ^ big_int(1), big_int(0));
1179        assert_eq!(1 as u32 ^ big_int(1), big_int(0));
1180        assert_eq!(1 as u64 ^ big_int(1), big_int(0));
1181        assert_eq!(1 as isize ^ big_int(1), big_int(0));
1182        assert_eq!(1 as usize ^ big_int(1), big_int(0));
1183        assert_eq!(big_int(1) ^ 1 as i32, big_int(0));
1184        assert_eq!(big_int(1) ^ 1 as i64, big_int(0));
1185        assert_eq!(big_int(1) ^ 1 as u32, big_int(0));
1186        assert_eq!(big_int(1) ^ 1 as u64, big_int(0));
1187        assert_eq!(big_int(1) ^ 1 as isize, big_int(0));
1188        assert_eq!(big_int(1) ^ 1 as usize, big_int(0));
1189        assert_eq!(big_int(1) ^ big_int(1), big_int(0));
1190        assert_eq!(big_int(1) ^ &big_int(1), big_int(0));
1191        assert_eq!(&big_int(1) ^ big_int(1), big_int(0));
1192        assert_eq!(&big_int(1) ^ &big_int(1), big_int(0));
1193
1194        // Shr
1195        assert_eq!(big_int(1) >> 1 as i32, big_int(0));
1196        assert_eq!(big_int(1) >> 1 as i64, big_int(0));
1197        assert_eq!(big_int(1) >> 1 as u32, big_int(0));
1198        assert_eq!(big_int(1) >> 1 as u64, big_int(0));
1199        assert_eq!(big_int(1) >> 1 as isize, big_int(0));
1200        assert_eq!(big_int(1) >> 1 as usize, big_int(0));
1201
1202        // Shl
1203        assert_eq!(big_int(1) << 1 as i32, big_int(2));
1204        assert_eq!(big_int(1) << 1 as i64, big_int(2));
1205        assert_eq!(big_int(1) << 1 as u32, big_int(2));
1206        assert_eq!(big_int(1) << 1 as u64, big_int(2));
1207        assert_eq!(big_int(1) << 1 as isize, big_int(2));
1208        assert_eq!(big_int(1) << 1 as usize, big_int(2));
1209
1210        assert_eq!(1 as i32 + big_int(1), big_int(2));
1211        assert_eq!(1 as i64 + big_int(1), big_int(2));
1212        assert_eq!(1 as u32 + big_int(1), big_int(2));
1213        assert_eq!(1 as u64 + big_int(1), big_int(2));
1214        assert_eq!(1 as isize + big_int(1), big_int(2));
1215        assert_eq!(1 as usize + big_int(1), big_int(2));
1216        assert_eq!(1 + big_int(1), big_int(2));
1217        assert_eq!(1 as i32 - big_int(1), big_int(0));
1218        assert_eq!(1 as i64 - big_int(1), big_int(0));
1219        assert_eq!(1 as u32 - big_int(1), big_int(0));
1220        assert_eq!(1 as u64 - big_int(1), big_int(0));
1221        assert_eq!(1 as isize - big_int(1), big_int(0));
1222        assert_eq!(1 as usize - big_int(1), big_int(0));
1223        assert_eq!(1 - big_int(1), big_int(0));
1224        assert_eq!(2 as i32 * big_int(2), big_int(4));
1225        assert_eq!(2 as i64 * big_int(2), big_int(4));
1226        assert_eq!(2 as u32 * big_int(2), big_int(4));
1227        assert_eq!(2 as u64 * big_int(2), big_int(4));
1228        assert_eq!(2 as isize * big_int(2), big_int(4));
1229        assert_eq!(2 as usize * big_int(2), big_int(4));
1230        assert_eq!(2 * big_int(2), big_int(4));
1231        assert_eq!(4 as i32 / big_int(2), big_int(2));
1232        assert_eq!(4 as i64 / big_int(2), big_int(2));
1233        assert_eq!(4 as u32 / big_int(2), big_int(2));
1234        assert_eq!(4 as u64 / big_int(2), big_int(2));
1235        assert_eq!(4 as isize / big_int(2), big_int(2));
1236        assert_eq!(4 as usize / big_int(2), big_int(2));
1237        assert_eq!(4 / big_int(2), big_int(2));
1238        assert_eq!(3 as i32 / big_int(2), big_int(1));
1239        assert_eq!(3 as i64 / big_int(2), big_int(1));
1240        assert_eq!(3 as u32 / big_int(2), big_int(1));
1241        assert_eq!(3 as u64 / big_int(2), big_int(1));
1242        assert_eq!(3 as isize / big_int(2), big_int(1));
1243        assert_eq!(3 as usize / big_int(2), big_int(1));
1244        assert_eq!(3 / big_int(2), big_int(1));
1245    }
1246
1247    #[test]
1248    fn bigint_div_rem_by_bigint() {
1249        assert_eq!(
1250            BigInt::div_rem(&big_int(3), &big_int(2)),
1251            (big_int(1), big_int(1))
1252        );
1253        assert_eq!(
1254            BigInt::div_rem(&big_int(10), &big_int(3)),
1255            (big_int(3), big_int(1))
1256        );
1257        assert_eq!(
1258            BigInt::div_rem(&big_int(7), &big_int(15)),
1259            (big_int(0), big_int(7))
1260        );
1261        assert_eq!(
1262            BigInt::div_rem(&big_int(8), &big_int(8)),
1263            (big_int(1), big_int(0))
1264        );
1265        assert_eq!(
1266            BigInt::div_rem(&big_int(-20), &big_int(5)),
1267            (big_int(-4), big_int(0))
1268        );
1269        assert_eq!(
1270            BigInt::div_rem(&big_int(0), &big_int(2)),
1271            (big_int(0), big_int(0))
1272        );
1273    }
1274
1275    #[test]
1276    fn bigint_op_float() {
1277        assert_eq!(big_int(1) + 1.0 as f64, big_decimal(2.0));
1278        assert_eq!(big_int(1) + 1.0 as f32, big_decimal(2.0));
1279        assert_eq!(big_int(1) + 1.0, big_decimal(2.0));
1280        assert_eq!(big_int(1) - 1.0 as f64, big_decimal(0.0));
1281        assert_eq!(big_int(1) - 1.0 as f32, big_decimal(0.0));
1282        assert_eq!(big_int(1) - 1.0, big_decimal(0.0));
1283        assert_eq!(big_int(2) * 2.0 as f64, big_decimal(4.0));
1284        assert_eq!(big_int(2) * 2.0 as f32, big_decimal(4.0));
1285        assert_eq!(big_int(2) * 2.0, big_decimal(4.0));
1286        assert_eq!(big_int(4) / 2.0 as f64, big_decimal(2.0));
1287        assert_eq!(big_int(4) / 2.0 as f32, big_decimal(2.0));
1288        assert_eq!(big_int(4) / 2.0, big_decimal(2.0));
1289    }
1290
1291    #[test]
1292    fn float_op_bigint() {
1293        assert_eq!(1.0 as f64 + big_int(1), big_decimal(2.0));
1294        assert_eq!(1.0 as f32 + big_int(1), big_decimal(2.0));
1295        assert_eq!(1.0 + big_int(1), big_decimal(2.0));
1296        assert_eq!(1.0 as f64 - big_int(1), big_decimal(0.0));
1297        assert_eq!(1.0 as f32 - big_int(1), big_decimal(0.0));
1298        assert_eq!(1.0 - big_int(1), big_decimal(0.0));
1299        assert_eq!(2.0 as f64 * big_int(2), big_decimal(4.0));
1300        assert_eq!(2.0 as f32 * big_int(2), big_decimal(4.0));
1301        assert_eq!(2.0 * big_int(2), big_decimal(4.0));
1302        assert_eq!(4.0 as f64 / big_int(2), big_decimal(2.0));
1303        assert_eq!(4.0 as f32 / big_int(2), big_decimal(2.0));
1304        assert_eq!(4.0 / big_int(2), big_decimal(2.0));
1305    }
1306
1307    #[test]
1308    fn bigint_op_bigdecimal() {
1309        assert_eq!(big_int(1) + big_decimal(1.0), big_decimal(2.0));
1310        assert_eq!(big_int(1) - big_decimal(1.0), big_decimal(0.0));
1311        assert_eq!(big_int(2) * big_decimal(2.0), big_decimal(4.0));
1312        assert_eq!(big_int(4) / big_decimal(2.0), big_decimal(2.0));
1313    }
1314
1315    #[test]
1316    fn bigdecimal_op_bigint() {
1317        assert_eq!(big_decimal(1.0) + big_int(1), big_decimal(2.0));
1318        assert_eq!(big_decimal(1.0) - big_int(1), big_decimal(0.0));
1319        assert_eq!(big_decimal(2.0) * big_int(2), big_decimal(4.0));
1320        assert_eq!(big_decimal(4.0) / big_int(2), big_decimal(2.0));
1321    }
1322
1323    #[test]
1324    fn bigint_bitshift() {
1325        let x = big_uint(0) & big_uint(1);
1326        assert_eq!(big_uint(0), x);
1327    }
1328
1329    #[test]
1330    fn bigint_divide_by_decimals() {
1331        assert_eq!(big_uint(50000).to_decimal(3), big_decimal(50.0));
1332
1333        assert_eq!(big_uint(112000000).to_decimal(5), big_decimal(1120.0));
1334
1335        assert_eq!(
1336            big_uint(11205450180000000000).to_decimal(18),
1337            big_decimal(11.20545018)
1338        );
1339
1340        assert_eq!(
1341            big_uint(112054501800000000).to_decimal(18),
1342            big_decimal(0.1120545018)
1343        );
1344
1345        assert_eq!(
1346            big_uint(11205450180000000000).to_decimal(20),
1347            big_decimal(0.1120545018)
1348        );
1349    }
1350
1351    #[test]
1352    fn bigdecimal_divide_by_decimals() {
1353        assert_eq!(
1354            BigDecimal::divide_by_decimals(big_decimal(50000.0), 3),
1355            big_decimal(50.0)
1356        );
1357
1358        assert_eq!(
1359            BigDecimal::divide_by_decimals(big_decimal(112000000.5), 5),
1360            big_decimal(1120.000005)
1361        );
1362
1363        assert_eq!(
1364            BigDecimal::divide_by_decimals(big_decimal(11205450180000000000.51), 18),
1365            big_decimal(11.20545018)
1366        );
1367
1368        assert_eq!(
1369            BigDecimal::divide_by_decimals(big_decimal(112054501800000000.51), 18),
1370            big_decimal(0.1120545018)
1371        );
1372
1373        assert_eq!(
1374            BigDecimal::divide_by_decimals(big_decimal(11205450180000000000.51), 20),
1375            big_decimal(0.1120545018)
1376        );
1377    }
1378}