1use core::ops::{Mul, MulAssign};
2
3use dashu_base::Gcd;
4use dashu_int::{IBig, UBig};
5
6use crate::{
7 helper_macros::{impl_binop_assign_by_taking, impl_binop_with_int, impl_binop_with_macro},
8 rbig::{RBig, Relaxed},
9 repr::Repr,
10};
11
12impl Repr {
13 #[inline]
14 fn sqr(&self) -> Self {
15 Self {
16 numerator: self.numerator.sqr().into(),
17 denominator: self.denominator.sqr(),
18 }
19 }
20
21 #[inline]
22 fn cubic(&self) -> Self {
23 Self {
24 numerator: self.numerator.cubic(),
25 denominator: self.denominator.cubic(),
26 }
27 }
28
29 #[inline]
30 fn pow(&self, n: usize) -> Self {
31 Self {
32 numerator: self.numerator.pow(n),
33 denominator: self.denominator.pow(n),
34 }
35 }
36}
37
38impl RBig {
39 #[inline]
50 pub fn sqr(&self) -> Self {
51 Self(self.0.sqr())
52 }
53
54 #[inline]
65 pub fn cubic(&self) -> Self {
66 Self(self.0.cubic())
67 }
68
69 #[inline]
80 pub fn pow(&self, n: usize) -> Self {
81 Self(self.0.pow(n))
82 }
83}
84
85macro_rules! impl_mul_with_rbig {
86 (
87 $a:ident, $b:ident, $c:ident, $d:ident,
88 $ra:ident, $rb:ident, $rc:ident, $rd:ident, $method:ident
89 ) => {{
90 let g_ad = $ra.gcd($rd);
92 let g_bc = $rb.gcd($rc);
93 RBig(Repr {
94 numerator: ($a / &g_ad).$method($c / &g_bc),
95 denominator: ($b / g_bc).$method($d / g_ad),
96 })
97 }};
98}
99
100impl_binop_with_macro!(impl Mul, mul, impl_mul_with_rbig);
101impl_binop_assign_by_taking!(impl MulAssign for RBig, mul_assign, mul);
102
103impl Relaxed {
104 #[inline]
108 pub fn sqr(&self) -> Self {
109 Self(self.0.sqr())
110 }
111
112 #[inline]
116 pub fn cubic(&self) -> Self {
117 Self(self.0.cubic())
118 }
119
120 #[inline]
124 pub fn pow(&self, n: usize) -> Self {
125 Self(self.0.pow(n))
126 }
127}
128
129macro_rules! impl_mul_with_relaxed {
130 (
131 $a:ident, $b:ident, $c:ident, $d:ident,
132 $ra:ident, $rb:ident, $rc:ident, $rd:ident, $method:ident
133 ) => {{
134 let _unused = ($ra, $rb, $rc, $rd);
135 Relaxed::from_parts($a.$method($c), $b.$method($d))
136 }};
137}
138impl_binop_with_macro!(impl Mul for Relaxed, mul, impl_mul_with_relaxed);
139impl_binop_assign_by_taking!(impl MulAssign for Relaxed, mul_assign, mul);
140
141macro_rules! impl_mul_int_with_rbig {
142 (
143 $a:ident, $b:ident, $i:ident,
144 $ra:ident, $rb:ident, $ri:ident, $method:ident
145 ) => {{
146 let _unused = ($ra, $rb, $ri);
147 let g = $rb.gcd($ri);
148 RBig(Repr {
149 numerator: $a.$method($i / &g),
150 denominator: $b / g,
151 })
152 }};
153}
154impl_binop_with_int!(impl Mul<UBig>, mul, impl_mul_int_with_rbig);
155impl_binop_with_int!(impl Mul<IBig>, mul, impl_mul_int_with_rbig);
156impl_binop_with_int!(impl Mul for UBig, mul, impl_mul_int_with_rbig);
157impl_binop_with_int!(impl Mul for IBig, mul, impl_mul_int_with_rbig);
158
159macro_rules! impl_mul_int_with_relaxed {
160 (
161 $a:ident, $b:ident, $i:ident,
162 $ra:ident, $rb:ident, $ri:ident, $method:ident
163 ) => {{
164 let _unused = ($ra, $rb, $ri);
165 Relaxed::from_parts($a.$method($i), $b)
166 }};
167}
168impl_binop_with_int!(impl Mul<UBig>, mul, Relaxed, impl_mul_int_with_relaxed);
169impl_binop_with_int!(impl Mul<IBig>, mul, Relaxed, impl_mul_int_with_relaxed);
170impl_binop_with_int!(impl Mul for UBig, mul, Relaxed, impl_mul_int_with_relaxed);
171impl_binop_with_int!(impl Mul for IBig, mul, Relaxed, impl_mul_int_with_relaxed);