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#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
24pub struct BigDecimal(bigdecimal::BigDecimal);
25
26impl BigDecimal {
27 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 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 big_decimal_amount.div(BigDecimal::new(BigInt::one(), decimals as i64))
90 }
91
92 pub fn absolute(&self) -> BigDecimal {
93 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#[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 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 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
823macro_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
965macro_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 #[test]
1127 fn int_op_bigint() {
1128 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 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 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 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 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 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 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}