1use crate::decimal::Decimal;
18use std::convert::TryFrom;
19use std::iter::{Product, Sum};
20use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign};
21
22impl Neg for Decimal {
23 type Output = Decimal;
24
25 #[inline]
26 fn neg(mut self) -> Self::Output {
27 self.neg_mut();
28 self
29 }
30}
31
32impl Neg for &'_ Decimal {
33 type Output = Decimal;
34
35 #[inline]
36 fn neg(self) -> Self::Output {
37 if !self.is_zero() {
38 unsafe { Decimal::from_raw_parts(self.int_val(), self.scale(), !self.is_sign_negative()) }
39 } else {
40 Decimal::ZERO
41 }
42 }
43}
44
45impl Add<&Decimal> for &Decimal {
46 type Output = Decimal;
47
48 #[inline(always)]
49 fn add(self, other: &Decimal) -> Self::Output {
50 match self.checked_add(other) {
51 Some(sum) => sum,
52 None => panic!("Addition overflowed"),
53 }
54 }
55}
56
57impl AddAssign<&Decimal> for Decimal {
58 #[inline(always)]
59 fn add_assign(&mut self, other: &Decimal) {
60 let result = self.add(other);
61 *self = result;
62 }
63}
64
65impl Sub<&Decimal> for &Decimal {
66 type Output = Decimal;
67
68 #[inline(always)]
69 fn sub(self, other: &Decimal) -> Decimal {
70 match self.checked_sub(other) {
71 Some(diff) => diff,
72 None => panic!("Subtraction overflowed"),
73 }
74 }
75}
76
77impl SubAssign<&Decimal> for Decimal {
78 #[inline(always)]
79 fn sub_assign(&mut self, other: &Decimal) {
80 let result = self.sub(other);
81 *self = result;
82 }
83}
84
85impl Mul<&Decimal> for &Decimal {
86 type Output = Decimal;
87
88 #[inline(always)]
89 fn mul(self, other: &Decimal) -> Decimal {
90 match self.checked_mul(other) {
91 Some(prod) => prod,
92 None => panic!("Multiplication overflowed"),
93 }
94 }
95}
96
97impl MulAssign<&Decimal> for Decimal {
98 #[inline(always)]
99 fn mul_assign(&mut self, other: &Decimal) {
100 let result = self.mul(other);
101 *self = result;
102 }
103}
104
105impl Div<&Decimal> for &Decimal {
106 type Output = Decimal;
107
108 #[inline(always)]
109 fn div(self, other: &Decimal) -> Decimal {
110 match self.checked_div(other) {
111 Some(quot) => quot,
112 None => panic!("Division by zero or overflowed"),
113 }
114 }
115}
116
117impl DivAssign<&Decimal> for Decimal {
118 #[inline(always)]
119 fn div_assign(&mut self, other: &Decimal) {
120 let result = self.div(other);
121 *self = result;
122 }
123}
124
125impl Rem<&Decimal> for &Decimal {
126 type Output = Decimal;
127
128 #[inline(always)]
129 fn rem(self, other: &Decimal) -> Decimal {
130 match self.checked_rem(other) {
131 Some(rem) => rem,
132 None => panic!("Division by zero or overflowed"),
133 }
134 }
135}
136
137impl RemAssign<&Decimal> for Decimal {
138 #[inline(always)]
139 fn rem_assign(&mut self, other: &Decimal) {
140 let result = self.rem(other);
141 *self = result;
142 }
143}
144
145impl Sum for Decimal {
146 #[inline(always)]
147 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
148 iter.fold(Decimal::ZERO, Add::add)
149 }
150}
151
152impl<'a> Sum<&'a Decimal> for Decimal {
153 #[inline(always)]
154 fn sum<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
155 iter.fold(Decimal::ZERO, Add::add)
156 }
157}
158
159impl Product for Decimal {
160 #[inline(always)]
161 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
162 iter.fold(Decimal::ONE, Mul::mul)
163 }
164}
165
166impl<'a> Product<&'a Decimal> for Decimal {
167 #[inline(always)]
168 fn product<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
169 iter.fold(Decimal::ONE, Mul::mul)
170 }
171}
172
173macro_rules! impl_arith_with_num {
174 ($op: ident { $method: ident } $int: ty) => {
175 impl $op<$int> for Decimal {
176 type Output = Decimal;
177
178 #[inline(always)]
179 fn $method(self, other: $int) -> Self::Output {
180 self.$method(&Decimal::from(other))
181 }
182 }
183
184 impl $op<$int> for &'_ Decimal {
185 type Output = Decimal;
186
187 #[inline(always)]
188 fn $method(self, other: $int) -> Self::Output {
189 self.$method(&Decimal::from(other))
190 }
191 }
192
193 impl $op<Decimal> for $int {
194 type Output = Decimal;
195
196 #[inline(always)]
197 fn $method(self, other: Decimal) -> Self::Output {
198 Decimal::from(self).$method(other)
199 }
200 }
201
202 impl $op<&'_ Decimal> for $int {
203 type Output = Decimal;
204
205 #[inline(always)]
206 fn $method(self, other: &'_ Decimal) -> Self::Output {
207 Decimal::from(self).$method(other)
208 }
209 }
210 };
211 ($op: ident { $method: ident } $($int: ty), * $(,)?) => {
212 $(impl_arith_with_num!($op { $method } $int);)*
213 };
214}
215
216macro_rules! impl_arith_try_with_num {
217 ($op: ident { $method: ident } $int: ty) => {
218 impl $op<$int> for Decimal {
219 type Output = Decimal;
220
221 #[inline(always)]
222 fn $method(self, other: $int) -> Self::Output {
223 self.$method(&Decimal::try_from(other).unwrap())
224 }
225 }
226
227 impl $op<$int> for &'_ Decimal {
228 type Output = Decimal;
229
230 #[inline(always)]
231 fn $method(self, other: $int) -> Self::Output {
232 self.$method(&Decimal::try_from(other).unwrap())
233 }
234 }
235
236 impl $op<Decimal> for $int {
237 type Output = Decimal;
238
239 #[inline(always)]
240 fn $method(self, other: Decimal) -> Self::Output {
241 Decimal::try_from(self).unwrap().$method(other)
242 }
243 }
244
245 impl $op<&'_ Decimal> for $int {
246 type Output = Decimal;
247
248 #[inline(always)]
249 fn $method(self, other: &'_ Decimal) -> Self::Output {
250 Decimal::try_from(self).unwrap().$method(other)
251 }
252 }
253 };
254 ($op: ident { $method: ident } $($int: ty), * $(,)?) => {
255 $(impl_arith_try_with_num!($op { $method } $int);)*
256 };
257}
258
259macro_rules! impl_arith {
260 ($op: ident { $method: ident }) => {
261 impl $op for Decimal {
262 type Output = Decimal;
263
264 #[inline(always)]
265 fn $method(self, other: Self) -> Self::Output {
266 (&self).$method(&other)
267 }
268 }
269
270 impl $op<&'_ Decimal> for Decimal {
271 type Output = Decimal;
272
273 #[inline(always)]
274 fn $method(self, other: &Decimal) -> Self::Output {
275 (&self).$method(other)
276 }
277 }
278
279 impl $op<Decimal> for &'_ Decimal {
280 type Output = Decimal;
281
282 #[inline(always)]
283 fn $method(self, other: Decimal) -> Self::Output {
284 self.$method(&other)
285 }
286 }
287
288 impl_arith_with_num!($op { $method } u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
289 impl_arith_try_with_num!($op { $method } f32, f64, i128, u128);
290 };
291}
292
293impl_arith!(Add { add });
294impl_arith!(Sub { sub });
295impl_arith!(Mul { mul });
296impl_arith!(Div { div });
297impl_arith!(Rem { rem });
298
299macro_rules! impl_arith_assign_with_num {
300 ($op: ident { $method: ident } $int: ty) => {
301 impl $op<$int> for Decimal {
302 #[inline(always)]
303 fn $method(&mut self, other: $int) {
304 self.$method(&Decimal::from(other))
305 }
306 }
307
308 impl $op<$int> for &mut Decimal {
309 #[inline(always)]
310 fn $method(&mut self, other: $int) {
311 (*self).$method(&Decimal::from(other))
312 }
313 }
314 };
315 ($op: ident { $method: ident } $($int: ty), * $(,)?) => {
316 $(impl_arith_assign_with_num!($op { $method } $int);)*
317 };
318}
319
320macro_rules! impl_arith_assign_try_with_num {
321 ($op: ident { $method: ident } $int: ty) => {
322 impl $op<$int> for Decimal {
323 #[inline(always)]
324 fn $method(&mut self, other: $int) {
325 self.$method(&Decimal::try_from(other).unwrap())
326 }
327 }
328
329 impl $op<$int> for &mut Decimal {
330 #[inline(always)]
331 fn $method(&mut self, other: $int) {
332 (*self).$method(&Decimal::try_from(other).unwrap())
333 }
334 }
335 };
336 ($op: ident { $method: ident } $($int: ty), * $(,)?) => {
337 $(impl_arith_assign_try_with_num!($op { $method } $int);)*
338 };
339}
340
341macro_rules! impl_arith_assign {
342 ($op: ident { $method: ident }) => {
343 impl $op<Decimal> for &mut Decimal {
344 #[inline(always)]
345 fn $method(&mut self, other: Decimal) {
346 (*self).$method(&other)
347 }
348 }
349
350 impl $op<&Decimal> for &mut Decimal {
351 #[inline(always)]
352 fn $method(&mut self, other: &Decimal) {
353 (*self).$method(other)
354 }
355 }
356
357 impl $op<Decimal> for Decimal {
358 #[inline(always)]
359 fn $method(&mut self, other: Decimal) {
360 self.$method(&other)
361 }
362 }
363
364 impl_arith_assign_with_num!($op { $method } u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
365 impl_arith_assign_try_with_num!($op { $method } f32, f64, i128, u128);
366 };
367}
368
369impl_arith_assign!(AddAssign { add_assign });
370impl_arith_assign!(SubAssign { sub_assign });
371impl_arith_assign!(MulAssign { mul_assign });
372impl_arith_assign!(DivAssign { div_assign });
373impl_arith_assign!(RemAssign { rem_assign });
374
375#[cfg(test)]
376mod tests {
377 use super::*;
378
379 #[test]
380 fn test_neg() {
381 fn assert_neg(val: &str, expected: &str) {
382 let val = val.parse::<Decimal>().unwrap();
383 let expected = expected.parse::<Decimal>().unwrap();
384 {
385 let neg_val = -val;
386 assert_eq!(neg_val, expected);
387 }
388 {
389 let neg_val = -(&val);
390 assert_eq!(neg_val, expected);
391 }
392 }
393
394 assert_neg("00000.00000", "0");
395 assert_neg("1.0", "-1");
396 assert_neg("-1.0", "1");
397 assert_neg("1.234", "-1.234");
398 assert_neg("-1.234", "1.234");
399 }
400
401 #[test]
402 fn test_add() {
403 fn assert_add(val1: &str, val2: &str, expected: &str) {
404 let var1 = val1.parse::<Decimal>().unwrap();
405 let var2 = val2.parse::<Decimal>().unwrap();
406 let expected = expected.parse::<Decimal>().unwrap();
407
408 let result = var1 + var2;
409 assert_eq!(result, expected);
410 }
411
412 assert_add("0.000000001", "100000000", "100000000.000000001");
413 assert_add("123456789.987654321", "-123456789.987654321", "0");
414 assert_add("987654321.123456789", "-987654321.123456789", "0");
415 assert_add("123456789.987654321", "987654321.123456789", "1111111111.11111111");
416 assert_add("123456789.987654321", "00000.00000", "123456789.987654321");
417 assert_add("123456789.987654321", "-987654321.123456789", "-864197531.135802468");
418 assert_add("00000.00000", "987654321.123456789", "987654321.123456789");
419 assert_add("00000.00000", "00000.00000", "0");
420 assert_add("00000.00000", "-987654321.123456789", "-987654321.123456789");
421 assert_add("-123456789.987654321", "987654321.123456789", "864197531.135802468");
422 assert_add("-123456789.987654321", "00000.00000", "-123456789.987654321");
423 assert_add("-123456789.987654321", "-987654321.123456789", "-1111111111.11111111");
424 assert_add("-1e28", "-1e122", "-1e122");
425 assert_add(
426 "0",
427 "0.00038758507034516434217352824488052003540",
428 "0.00038758507034516434217352824488052003540",
429 );
430 assert_add(
431 "1",
432 "0.00038758507034516434217352824488052003540",
433 "1.00038758507034516434217352824488052",
434 );
435 assert_add(
436 "99999999999999999999999999999999999999e80",
437 "99999999999999999999999999999999999999e-80",
438 "99999999999999999999999999999999999999e80",
439 );
440 assert_add("1e-31", "1e-105", "1e-31");
441 assert_add("1e76", "123456789", "1e76");
442 assert_add("0", "1e-127", "1e-127");
443 assert_add("0", "1e-90", "1e-90");
444 assert_add("0", "-1e-127", "-1e-127");
445 assert_add("0", "-1e-90", "-1e-90");
446 }
447
448 #[test]
449 fn test_sub() {
450 fn assert_sub(val1: &str, val2: &str, expected1: &str, expected2: &str) {
451 let var1 = val1.parse::<Decimal>().unwrap();
452 let var2 = val2.parse::<Decimal>().unwrap();
453 let expected1 = expected1.parse::<Decimal>().unwrap();
454 let expected2 = expected2.parse::<Decimal>().unwrap();
455
456 let result1 = var1 - var2;
457 assert_eq!(result1, expected1);
458
459 let result2 = var2 - var1;
460 assert_eq!(result2, expected2);
461 }
462
463 assert_sub("0.000000001", "100000000", "-99999999.999999999", "99999999.999999999");
464 assert_sub(
465 "123456789.987654321",
466 "123456789.987654321",
467 "0.000000000",
468 "0.000000000",
469 );
470 assert_sub(
471 "987654321.123456789",
472 "987654321.123456789",
473 "0.000000000",
474 "0.000000000",
475 );
476 assert_sub(
477 "123456789.987654321",
478 "987654321.123456789",
479 "-864197531.135802468",
480 "864197531.135802468",
481 );
482 assert_sub(
483 "123456789.987654321",
484 "00000.00000",
485 "123456789.987654321",
486 "-123456789.987654321",
487 );
488 assert_sub(
489 "123456789.987654321",
490 "-987654321.123456789",
491 "1111111111.111111110",
492 "-1111111111.111111110",
493 );
494 assert_sub(
495 "00000.00000",
496 "987654321.123456789",
497 "-987654321.123456789",
498 "987654321.123456789",
499 );
500 assert_sub("00000.00000", "00000.00000", "0.00000", "0.00000");
501 assert_sub(
502 "00000.00000",
503 "-987654321.123456789",
504 "987654321.123456789",
505 "-987654321.123456789",
506 );
507 assert_sub(
508 "-123456789.987654321",
509 "987654321.123456789",
510 "-1111111111.111111110",
511 "1111111111.111111110",
512 );
513 assert_sub(
514 "-123456789.987654321",
515 "00000.00000",
516 "-123456789.987654321",
517 "123456789.987654321",
518 );
519 assert_sub(
520 "-123456789.987654321",
521 "-987654321.123456789",
522 "864197531.135802468",
523 "-864197531.135802468",
524 );
525 assert_sub("-1e28", "-1e122", "1e122", "-1e122");
526 assert_sub(
527 "0",
528 "0.00038758507034516434217352824488052003540",
529 "-0.00038758507034516434217352824488052003540",
530 "0.00038758507034516434217352824488052003540",
531 );
532 assert_sub(
533 "1",
534 "0.00038758507034516434217352824488052003540",
535 "0.99961241492965483565782647175511947996",
536 "-0.99961241492965483565782647175511947996",
537 );
538 assert_sub(
539 "99999999999999999999999999999999999999e80",
540 "99999999999999999999999999999999999999e-80",
541 "99999999999999999999999999999999999999e80",
542 "-99999999999999999999999999999999999999e80",
543 );
544 }
545
546 #[test]
547 fn test_mul() {
548 fn assert_mul(val1: &str, val2: &str, expected: &str) {
549 let var1 = val1.parse::<Decimal>().unwrap();
550 let var2 = val2.parse::<Decimal>().unwrap();
551 let expected = expected.parse::<Decimal>().unwrap();
552
553 let result = var1 * var2;
554 assert_eq!(result, expected);
555 }
556
557 assert_mul("0.000000001", "100000000", "0.1");
558 assert_mul(
559 "123456789.987654321",
560 "-123456789.987654321",
561 "-15241578994055784.200731595789971041",
562 );
563 assert_mul(
564 "987654321.123456789",
565 "-987654321.123456789",
566 "-975461058033836303.240512116750190521",
567 );
568 assert_mul(
569 "123456789.987654321",
570 "987654321.123456789",
571 "121932632103337905.662094193112635269",
572 );
573 assert_mul("123456789.987654321", "00000.00000", "0");
574 assert_mul(
575 "123456789.987654321",
576 "-987654321.123456789",
577 "-121932632103337905.662094193112635269",
578 );
579 assert_mul("00000.00000", "987654321.123456789", "0");
580 assert_mul("00000.00000", "00000.00000", "0");
581 assert_mul("00000.00000", "-987654321.123456789", "0");
582 assert_mul(
583 "-123456789.987654321",
584 "987654321.123456789",
585 "-121932632103337905.662094193112635269",
586 );
587 assert_mul("-123456789.987654321", "00000.00000", "0");
588 assert_mul(
589 "-123456789.987654321",
590 "-987654321.123456789",
591 "121932632103337905.662094193112635269",
592 );
593 }
594
595 #[test]
596 fn test_div() {
597 fn assert_div(val1: &str, val2: &str, expected: &str) {
598 let var1 = val1.parse::<Decimal>().unwrap();
599 let var2 = val2.parse::<Decimal>().unwrap();
600 let expected = expected.parse::<Decimal>().unwrap();
601
602 let result = var1 / var2;
603 assert_eq!(result, expected);
604 }
605
606 assert_div("0.000000001", "100000000", "0.00000000000000001");
607 assert_div("100000000", "0.000000001", "100000000000000000");
608 assert_div("123456789.987654321", "123456789.987654321", "1");
609 assert_div("987654321.123456789", "987654321.123456789", "1");
610 assert_div(
611 "123456789.987654321",
612 "987654321.123456789",
613 "0.12499999984531250017595703104984887718",
614 );
615 assert_div(
616 "987654321.123456789",
617 "123456789.987654321",
618 "8.000000009900000000990000000099",
619 );
620 assert_div("00000.00000", "123456789.987654321", "0");
621 assert_div(
622 "123456789.987654321",
623 "-987654321.123456789",
624 "-0.12499999984531250017595703104984887718",
625 );
626 assert_div(
627 "-987654321.123456789",
628 "123456789.987654321",
629 "-8.000000009900000000990000000099",
630 );
631 assert_div("00000.00000", "987654321.123456789", "0");
632 assert_div("00000.00000", "-987654321.123456789", "0");
633 assert_div(
634 "-123456789.987654321",
635 "987654321.123456789",
636 "-0.12499999984531250017595703104984887718",
637 );
638 assert_div(
639 "987654321.123456789",
640 "-123456789.987654321",
641 "-8.000000009900000000990000000099",
642 );
643 assert_div("00000.00000", "-123456789.987654321", "0");
644 assert_div(
645 "-123456789.987654321",
646 "-987654321.123456789",
647 "0.12499999984531250017595703104984887718",
648 );
649 assert_div(
650 "-987654321.123456789",
651 "-123456789.987654321",
652 "8.000000009900000000990000000099",
653 );
654 assert_div("1", "3", "0.33333333333333333333333333333333333333");
655 assert_div("1", "33", "0.030303030303030303030303030303030303030");
656 assert_div(
657 "-3.1415926",
658 "-0.12345678901234567890123456789012345678",
659 "25.446900289022102624101133879320318304",
660 );
661 }
662
663 #[test]
664 fn test_rem() {
665 fn assert_rem(val1: &str, val2: &str, expected: &str) {
666 let var1 = val1.parse::<Decimal>().unwrap();
667 let var2 = val2.parse::<Decimal>().unwrap();
668 let expected = expected.parse::<Decimal>().unwrap();
669
670 let result = var1 % var2;
671 assert_eq!(result, expected);
672 }
673
674 assert_rem("0.000000001", "100000000", "0.000000001");
675 assert_rem("100000000", "0.000000001", "0.000000000");
676 assert_rem("123456789.987654321", "123456789.987654321", "0");
677 assert_rem("987654321.123456789", "987654321.123456789", "0");
678 assert_rem("123456789.987654321", "987654321.123456789", "123456789.987654321");
679 assert_rem("987654321.123456789", "123456789.987654321", "1.222222221");
680 assert_rem("00000.00000", "123456789.987654321", "0");
681 assert_rem("123456789.987654321", "-987654321.123456789", "123456789.987654321");
682 assert_rem("-987654321.123456789", "123456789.987654321", "-1.222222221");
683 assert_rem("00000.00000", "987654321.123456789", "0.000000000");
684 assert_rem("00000.00000", "-987654321.123456789", "0.000000000");
685 assert_rem("-123456789.987654321", "987654321.123456789", "-123456789.987654321");
686 assert_rem("987654321.123456789", "-123456789.987654321", "1.222222221");
687 assert_rem("00000.00000", "-123456789.987654321", "0.000000000");
688 assert_rem("-123456789.987654321", "-987654321.123456789", "-123456789.987654321");
689 assert_rem("-987654321.123456789", "-123456789.987654321", "-1.222222221");
690 assert_rem("100", "5", "0");
691 assert_rem("2e1", "1", "0");
692 assert_rem("2", "1", "0");
693 assert_rem("1", "3", "1");
694 assert_rem("1", "0.5", "0");
695 assert_rem("1.5", "1", "0.5");
696 assert_rem("1", "3e-2", "1e-2");
697 assert_rem("10", "0.003", "0.001");
698 assert_rem("3", "2", "1");
699 assert_rem("-3", "2", "-1");
700 assert_rem("3", "-2", "1");
701 assert_rem("-3", "-2", "-1");
702 assert_rem("-3", "-1", "0");
703 assert_rem("12.34", "1.233", "0.01");
704 assert_rem("5e42", "0.3", "0.2");
705 assert_rem("-5e42", "0.3", "-0.2");
706 assert_rem("5e42", "-0.3", "0.2");
707 assert_rem("-5e42", "-0.3", "-0.2");
708 assert_rem("5e42", "0.03", "0.02");
709 assert_rem("5e42", "3", "2");
710 assert_rem("5e60", "3", "2");
711 assert_rem("5e60", "300", "200");
712 assert_rem("5e76", "3", "2");
713 assert_rem("5e77", "3", "2");
714 assert_rem("5e-42", "3e-84", "2e-84");
715 assert_rem("5e125", "3e-130", "2e-130");
716 assert_rem("4e125", "3e-130", "1e-130");
717 assert_rem("99999999999999999999999999999999999999e80", "7e-130", "1e-130");
718 assert_rem("3", "5e42", "3");
719 assert_rem("1e10", "9223", "8365");
720 assert_rem("1e20", "9223", "7547");
721 assert_rem("1e30", "9223", "8443");
722 assert_rem("1e40", "9223", "5184");
723 assert_rem("1e50", "9223", "6837");
724 assert_rem("1e60", "9223", "8905");
725 assert_rem("1e70", "9223", "5377");
726 assert_rem("1e80", "9223", "7257");
727 assert_rem("1e90", "9223", "8242");
728 assert_rem("1e100", "9223", "2405");
729 assert_rem("1e110", "9223", "2462");
730 assert_rem("1e120", "9223", "8894");
731 assert_rem("1e125", "9223", "7664");
732 assert_rem("1.234172907e125", "9223", "5190");
733 assert_rem("333.456", "7", "4.456");
734 assert_rem("333.456", "7.7", "2.356");
735 assert_rem("333.456", "7.7654", "7.3092");
736 assert_rem("323", "7.7654", "4.6186");
737 assert_rem("0.0003456", "0.00000000234", "7.2e-10");
738 assert_rem("0.3456", "9.234e-130", "2.484e-130");
739 assert_rem("0.0003456", "0.234", "0.0003456");
740 }
741
742 #[test]
743 fn test_sum() {
744 fn assert_sum(vals: &[&str], expected: &str) {
745 let result: Decimal = vals.iter().map(|val| val.parse::<Decimal>().unwrap()).sum();
746 let expected = expected.parse::<Decimal>().unwrap();
747 assert_eq!(result, expected);
748 }
749
750 assert_sum(&["1", "10", "100", "1000", "10000"], "11111");
751 assert_sum(&["-1", "-10", "-100", "-1000", "-10000"], "-11111");
752 assert_sum(&["0", "0", "0", "0", "0"], "0");
753 }
754
755 #[test]
756 fn test_product() {
757 fn assert_product(vals: &[&str], expected: &str) {
758 let result: Decimal = vals.iter().map(|val| val.parse::<Decimal>().unwrap()).product();
759 let expected = expected.parse::<Decimal>().unwrap();
760 assert_eq!(result, expected);
761 }
762
763 assert_product(&["1", "2", "3", "4", "5"], "120");
764 assert_product(&["-1", "-2", "-3", "-4", "-5"], "-120");
765 assert_product(&["0", "0", "0", "0", "0"], "0");
766 }
767}