bigdecimal/
impl_ops_mul.rs1use super::*;
5
6impl<'a, N: Into<BigDecimalRef<'a>>> Mul<N> for BigDecimal {
7 type Output = BigDecimal;
8
9 #[inline]
10 fn mul(mut self, rhs: N) -> Self::Output {
11 self.mul_assign(rhs.into());
12 self
13 }
14}
15
16impl<'a, 'b, N: Into<BigDecimalRef<'a>>> Mul<N> for BigDecimalRef<'b> {
17 type Output = BigDecimal;
18
19 #[inline]
20 fn mul(self, rhs: N) -> Self::Output {
21 let rhs = rhs.into();
22 if self.is_one_quickcheck() == Some(true) {
23 return rhs.to_owned();
24 }
25
26 let mut lhs = self.to_owned();
27 if rhs.is_one_quickcheck() != Some(true) {
28 lhs.mul_assign(rhs);
29 }
30 lhs
31 }
32}
33
34impl Mul<BigDecimal> for BigDecimal {
35 type Output = BigDecimal;
36
37 #[inline]
38 fn mul(mut self, rhs: BigDecimal) -> BigDecimal {
39 if self.is_one_quickcheck() == Some(true) {
40 return rhs;
41 }
42 if rhs.is_one_quickcheck() != Some(true) {
43 self.scale += rhs.scale;
44 self.int_val *= rhs.int_val;
45 }
46 self
47 }
48}
49
50impl Mul<BigDecimal> for &BigDecimal {
51 type Output = BigDecimal;
52
53 #[inline]
54 fn mul(self, rhs: BigDecimal) -> BigDecimal {
55 rhs * self
56 }
57}
58
59impl Mul<&BigDecimal> for &BigDecimal {
60 type Output = BigDecimal;
61
62 #[inline]
63 fn mul(self, rhs: &BigDecimal) -> BigDecimal {
64 if self.is_one_quickcheck() == Some(true) {
65 rhs.normalized()
66 } else if rhs.is_one_quickcheck() == Some(true) {
67 self.normalized()
68 } else {
69 let scale = self.scale + rhs.scale;
70 BigDecimal::new(&self.int_val * &rhs.int_val, scale)
71 }
72 }
73}
74
75impl Mul<BigInt> for BigDecimal {
76 type Output = BigDecimal;
77
78 #[inline]
79 fn mul(mut self, rhs: BigInt) -> BigDecimal {
80 self.int_val *= rhs;
81 self
82 }
83}
84
85impl Mul<BigInt> for &BigDecimal {
86 type Output = BigDecimal;
87
88 #[inline]
89 fn mul(self, mut rhs: BigInt) -> BigDecimal {
90 rhs *= &self.int_val;
91 BigDecimal::new(rhs, self.scale)
92 }
93}
94
95
96impl Mul<BigDecimal> for BigInt {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<BigDecimal>::mul for BigInt);
98impl Mul<&BigDecimal> for BigInt {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<&BigDecimal>::mul for BigInt);
99impl Mul<BigDecimal> for &BigInt {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<BigDecimal>::mul for &BigInt);
100impl Mul<&BigDecimal> for &BigInt {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<&BigDecimal>::mul for &BigInt);
101impl Mul<&BigInt> for &BigDecimal {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigInt) -> Self::Output {
Mul::mul(BigDecimalRef::from(self), rhs)
}
}forward_bigdecimalref_binop!(impl Mul<&BigInt>::mul for &BigDecimal);
102
103
104impl Mul<BigUint> for BigDecimal {
105 type Output = BigDecimal;
106
107 #[inline]
108 fn mul(mut self, rhs: BigUint) -> BigDecimal {
109 self *= rhs;
110 self
111 }
112}
113
114impl Mul<BigUint> for &BigDecimal {
115 type Output = BigDecimal;
116
117 #[inline]
118 fn mul(self, rhs: BigUint) -> BigDecimal {
119 self * BigInt::from(rhs)
120 }
121}
122
123
124impl Mul<BigDecimal> for BigUint {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<BigDecimal>::mul for BigUint);
126impl Mul<&BigDecimal> for BigUint {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<&BigDecimal>::mul for BigUint);
127impl Mul<BigDecimal> for &BigUint {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<BigDecimal>::mul for &BigUint);
128impl Mul<&BigDecimal> for &BigUint {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigDecimal) -> Self::Output { Mul::mul(rhs, self) }
}forward_communative_binop!(impl Mul<&BigDecimal>::mul for &BigUint);
129impl Mul<&BigUint> for &BigDecimal {
type Output = BigDecimal;
#[inline]
fn mul(self, rhs: &BigUint) -> Self::Output {
Mul::mul(BigDecimalRef::from(self), rhs)
}
}forward_bigdecimalref_binop!(impl Mul<&BigUint>::mul for &BigDecimal);
130
131impl<'a, N: Into<BigDecimalRef<'a>>> MulAssign<N> for BigDecimal {
132 #[inline]
133 fn mul_assign(&mut self, rhs: N) {
134 let rhs = rhs.into();
135 crate::arithmetic::multiplication::mulassign_bigdecimal_ref(self, rhs);
136 }
137}
138
139impl MulAssign<BigDecimal> for BigDecimal {
140 #[inline]
141 fn mul_assign(&mut self, rhs: BigDecimal) {
142 if self.is_one_quickcheck() == Some(true) {
143 self.int_val = rhs.int_val;
144 self.scale = rhs.scale;
145 } else if rhs.is_one_quickcheck() == Some(true) {
146 } else {
148 self.scale += rhs.scale;
149 self.int_val *= rhs.int_val;
150 }
151 }
152}
153
154impl MulAssign<BigInt> for BigDecimal {
155 #[inline]
156 fn mul_assign(&mut self, rhs: BigInt) {
157 self.int_val.mul_assign(rhs)
158 }
159}
160
161impl MulAssign<BigUint> for BigDecimal {
162 #[inline]
163 fn mul_assign(&mut self, rhs: BigUint) {
164 self.mul_assign(BigInt::from(rhs))
165 }
166}
167
168#[cfg(test)]
169#[allow(non_snake_case)]
170mod bigdecimal_tests {
171 use super::*;
172 use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
173 use num_bigint;
174 use paste::paste;
175
176 macro_rules! impl_test {
177 ($name:ident; $a:literal * $b:literal => $expected:literal) => {
178 #[test]
179 fn $name() {
180 let mut a: BigDecimal = $a.parse().unwrap();
181 let b: BigDecimal = $b.parse().unwrap();
182 let expected: BigDecimal = $expected.parse().unwrap();
183
184 let prod = a.clone() * b.clone();
185 assert_eq!(prod, expected);
186 assert_eq!(prod.scale, expected.scale);
187
188 let prod = a.clone() * &b;
189 assert_eq!(prod, expected);
190 let prod = &a * b.clone();
193 assert_eq!(prod, expected);
194 let prod = &a * &b;
197 assert_eq!(prod, expected);
198 assert_eq!(prod.scale, expected.scale);
199
200 a *= b;
201 assert_eq!(a, expected);
202 assert_eq!(a.scale, expected.scale);
203 }
204 };
205 ($name:ident; $bigt:ty; $a:literal * $b:literal => $expected:literal) => {
206 #[test]
207 fn $name() {
208 let a: BigDecimal = $a.parse().unwrap();
209 let b: $bigt = $b.parse().unwrap();
210 let c: BigDecimal = $expected.parse().unwrap();
211
212 let prod = a.clone() * b.clone();
213 assert_eq!(prod, c);
214 assert_eq!(prod.scale, c.scale);
215
216 let prod = b.clone() * a.clone();
217 assert_eq!(prod, c);
218 assert_eq!(prod.scale, c.scale);
219
220 let prod = a.clone() * &b;
221 assert_eq!(prod, c);
222 assert_eq!(prod.scale, c.scale);
223
224 let prod = b.clone() * &a;
225 assert_eq!(prod, c);
226 let prod = &a * b.clone();
229 assert_eq!(prod, c);
230 assert_eq!(prod.scale, c.scale);
231
232 let prod = &b * a.clone();
233 assert_eq!(prod, c);
234 let prod = &a * &b;
237 assert_eq!(prod, c);
238 let prod = &b * &a;
241 assert_eq!(prod, c);
242 }
244 };
245 }
246
247 impl_test!(case_2_1; "2" * "1" => "2");
248 impl_test!(case_12d34_1d234; "12.34" * "1.234" => "15.22756");
249 impl_test!(case_2e1_1; "2e1" * "1" => "2e1");
250 impl_test!(case_3_d333333; "3" * ".333333" => "0.999999");
251 impl_test!(case_2389472934723_209481029831; "2389472934723" * "209481029831" => "500549251119075878721813");
252 impl_test!(case_1ed450_1e500; "1e-450" * "1e500" => "0.1e51");
253 impl_test!(case_n995052931ddd_4d523087321; "-995052931372975485719.533153137" * "4.523087321" => "-4500711297616988541501.836966993116075977");
254 impl_test!(case_995052931ddd_n4d523087321; "995052931372975485719.533153137" * "-4.523087321" => "-4500711297616988541501.836966993116075977");
255 impl_test!(case_n8d37664968_n4d523087321; "-8.37664968" * "-1.9086963714056968482094712882596748" => "15.988480848752691653730876239769592670324064");
256 impl_test!(case_n8d37664968_0; "-8.37664968" * "0" => "0.00000000");
257
258 impl_test!(case_8d561_10; BigInt; "8.561" * "10" => "85.610");
259
260 impl_test!(case_10000_638655273892892437; BigInt; "10000" * "638655273892892437" => "6386552738928924370000");
262 impl_test!(case_1en10_n9056180052657301; BigInt; "1e-10" * "-9056180052657301" => "-905618.0052657301");
263 impl_test!(case_n9en1_n368408638655273892892437473; BigInt; "-9e-1" * "-368408638655273892892437473" => "331567774789746503603193725.7");
264 impl_test!(case_n1d175470587012343730098_577575785; BigInt; "-1.175470587012343730098" * "577575785" => "-678923347.038065234601180476930");
265
266 impl_test!(case_1d000000_7848321491728058276; BigInt; "1.000000" * "7848321491728058276" => "7848321491728058276.000000");
267 impl_test!(case_16535178640845d04844_1; BigInt; "16535178640845.04844" * "1" => "16535178640845.04844");
268
269 impl_test!(case_1d000000_u7848321491728058276; BigUint; "1.000000" * "7848321491728058276" => "7848321491728058276.000000");
270 impl_test!(case_16535178640845d04844_u1; BigUint; "16535178640845.04844" * "1" => "16535178640845.04844");
271}