qfall_math/rational/q/arithmetic/
mul.rs1use super::super::Q;
12use crate::{
13 integer::Z,
14 macros::arithmetics::{
15 arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
16 arithmetic_between_types, arithmetic_trait_borrowed_to_owned,
17 arithmetic_trait_mixed_borrowed_owned,
18 },
19};
20use flint_sys::fmpq::{fmpq_mul, fmpq_mul_fmpz, fmpq_mul_si, fmpq_mul_ui};
21use std::ops::{Mul, MulAssign};
22
23impl MulAssign<&Q> for Q {
24 fn mul_assign(&mut self, other: &Self) {
49 unsafe { fmpq_mul(&mut self.value, &self.value, &other.value) };
50 }
51}
52impl MulAssign<&Z> for Q {
53 fn mul_assign(&mut self, other: &Z) {
55 unsafe { fmpq_mul_fmpz(&mut self.value, &self.value, &other.value) };
56 }
57}
58impl MulAssign<i64> for Q {
59 fn mul_assign(&mut self, other: i64) {
61 unsafe { fmpq_mul_si(&mut self.value, &self.value, other) };
62 }
63}
64impl MulAssign<u64> for Q {
65 fn mul_assign(&mut self, other: u64) {
67 unsafe { fmpq_mul_ui(&mut self.value, &self.value, other) };
68 }
69}
70impl MulAssign<f64> for Q {
71 fn mul_assign(&mut self, other: f64) {
73 let other = Q::from(other);
74
75 unsafe { fmpq_mul(&mut self.value, &self.value, &other.value) };
76 }
77}
78
79arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, Q, Q);
80arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, Q, Z);
81arithmetic_assign_between_types!(MulAssign, mul_assign, Q, i64, i32 i16 i8);
82arithmetic_assign_between_types!(MulAssign, mul_assign, Q, u64, u32 u16 u8);
83arithmetic_assign_between_types!(MulAssign, mul_assign, Q, f64, f32);
84
85impl Mul for &Q {
86 type Output = Q;
87 fn mul(self, other: Self) -> Self::Output {
109 let mut out = Q::default();
110 unsafe {
111 fmpq_mul(&mut out.value, &self.value, &other.value);
112 }
113 out
114 }
115}
116
117arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, Q, Q);
118arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, Q, Q);
119arithmetic_between_types!(Mul, mul, Q, Q, i64 i32 i16 i8 u64 u32 u16 u8 f32 f64);
120
121impl Mul<&Z> for &Q {
122 type Output = Q;
123
124 fn mul(self, other: &Z) -> Self::Output {
147 let mut out = Q::default();
148 unsafe {
149 fmpq_mul_fmpz(&mut out.value, &self.value, &other.value);
150 }
151 out
152 }
153}
154
155arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, Z, Q);
156arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, Z, Q);
157
158#[cfg(test)]
159mod test_mul_assign {
160 use crate::{integer::Z, rational::Q};
161
162 #[test]
164 fn correct_small() {
165 let mut a = Q::MINUS_ONE;
166 let b = Q::MINUS_ONE;
167 let c = Q::ZERO;
168 let d = Q::from((-1, 2));
169
170 a *= &b;
171 assert_eq!(1, a);
172 a *= &b;
173 assert_eq!(-1, a);
174 a *= &d;
175 assert_eq!(Q::from((1, 2)), a);
176 a *= &c;
177 assert_eq!(0, a);
178 }
179
180 #[test]
182 fn correct_large() {
183 let mut a: Q = Q::from((2, u64::MAX));
184 let b = Q::from(u64::MAX);
185
186 a *= b;
187
188 assert_eq!(a, Q::from(2));
189 }
190
191 #[test]
193 fn availability() {
194 let mut a = Q::from((1, 2));
195 let b = Q::from((4, 5));
196 let c = Z::ONE;
197
198 a *= &b;
199 a *= b;
200 a *= &c;
201 a *= c;
202 a *= 0.5_f64;
203 a *= 0.5_f32;
204 a *= 1_u8;
205 a *= 1_u16;
206 a *= 1_u32;
207 a *= 1_u64;
208 a *= 1_i8;
209 a *= 1_i16;
210 a *= 1_i32;
211 a *= 1_i64;
212 }
213}
214
215#[cfg(test)]
216mod test_mul {
217 use super::Q;
218 use std::str::FromStr;
219
220 #[test]
222 fn mul() {
223 let a: Q = Q::from(2);
224 let b: Q = Q::from((42, 2));
225 let c: Q = a * b;
226 assert_eq!(c, Q::from(42));
227 }
228
229 #[test]
231 fn mul_borrow() {
232 let a: Q = Q::from(2);
233 let b: Q = Q::from((42, 2));
234 let c: Q = &a * &b;
235 assert_eq!(c, Q::from(42));
236 }
237
238 #[test]
240 fn mul_first_borrowed() {
241 let a: Q = Q::from(4);
242 let b: Q = Q::from((42, 10));
243 let c: Q = &a * b;
244 assert_eq!(c, Q::from((168, 10)));
245 }
246
247 #[test]
249 fn mul_second_borrowed() {
250 let a: Q = Q::from(2);
251 let b: Q = Q::from((42, 2));
252 let c: Q = a * &b;
253 assert_eq!(c, Q::from(42));
254 }
255
256 #[test]
258 fn mul_large() {
259 let a: Q = Q::from(i64::MAX);
260 let b: Q = Q::from(2);
261 let c: Q = Q::from((1, i32::MAX));
262 let d: Q = Q::from((1, u32::MAX));
263
264 let e: Q = &a * &b;
265 let f: Q = c * d;
266
267 assert_eq!(e, Q::from(u64::MAX - 1));
268 assert_eq!(
269 f,
270 Q::from_str(&format!(
271 "1/{}",
272 u64::from(u32::MAX) * u64::from((u32::MAX - 1) / 2)
273 ))
274 .unwrap()
275 );
276 }
277}
278
279#[cfg(test)]
280mod test_mul_between_q_and_z {
281 use crate::integer::Z;
282 use crate::rational::Q;
283
284 #[test]
286 fn mul() {
287 let a: Q = Q::from((5, 7));
288 let b: Z = Z::from(4);
289 let c: Q = a * b;
290 assert_eq!(c, Q::from((20, 7)));
291 }
292
293 #[test]
295 fn mul_borrow() {
296 let a: Q = Q::from((5, 7));
297 let b: Z = Z::from(4);
298 let c: Q = &a * &b;
299 assert_eq!(c, Q::from((20, 7)));
300 }
301
302 #[test]
304 fn mul_first_borrowed() {
305 let a: Q = Q::from((5, 7));
306 let b: Z = Z::from(4);
307 let c: Q = &a * b;
308 assert_eq!(c, Q::from((20, 7)));
309 }
310
311 #[test]
313 fn mul_second_borrowed() {
314 let a: Q = Q::from((5, 7));
315 let b: Z = Z::from(4);
316 let c: Q = a * &b;
317 assert_eq!(c, Q::from((20, 7)));
318 }
319
320 #[test]
322 fn mul_large_numbers() {
323 let a: Q = Q::from((u64::MAX, 2));
324 let b: Q = Q::from((1, u64::MAX));
325 let c: Z = Z::from(u64::MAX);
326
327 let d: Q = a * &c;
328 let e: Q = b * c;
329
330 assert_eq!(d, Q::from(u64::MAX) * Q::from((u64::MAX, 2)));
331 assert_eq!(e, Q::from((1, u64::MAX)) * Q::from(u64::MAX));
332 }
333}
334
335#[cfg(test)]
336mod test_mul_between_types {
337 use crate::rational::Q;
338
339 #[test]
341 #[allow(clippy::op_ref)]
342 fn mul() {
343 let a: Q = Q::from(42);
344 let b: u64 = 1;
345 let c: u32 = 1;
346 let d: u16 = 1;
347 let e: u8 = 1;
348 let f: i64 = 1;
349 let g: i32 = 1;
350 let h: i16 = 1;
351 let i: i8 = 1;
352 let j: f32 = 0.3;
353 let k: f64 = 0.3;
354
355 let _: Q = &a * &b;
356 let _: Q = &a * &c;
357 let _: Q = &a * &d;
358 let _: Q = &a * &e;
359 let _: Q = &a * &f;
360 let _: Q = &a * &g;
361 let _: Q = &a * &h;
362 let _: Q = &a * &i;
363 let _: Q = &a * &j;
364 let _: Q = &a * &k;
365
366 let _: Q = &b * &a;
367 let _: Q = &c * &a;
368 let _: Q = &d * &a;
369 let _: Q = &e * &a;
370 let _: Q = &f * &a;
371 let _: Q = &g * &a;
372 let _: Q = &h * &a;
373 let _: Q = &i * &a;
374 let _: Q = &j * &a;
375 let _: Q = &k * &a;
376
377 let _: Q = &a * b;
378 let _: Q = &a * c;
379 let _: Q = &a * d;
380 let _: Q = &a * e;
381 let _: Q = &a * f;
382 let _: Q = &a * g;
383 let _: Q = &a * h;
384 let _: Q = &a * i;
385 let _: Q = &a * j;
386 let _: Q = &a * k;
387
388 let _: Q = &b * Q::from(42);
389 let _: Q = &c * Q::from(42);
390 let _: Q = &d * Q::from(42);
391 let _: Q = &e * Q::from(42);
392 let _: Q = &f * Q::from(42);
393 let _: Q = &g * Q::from(42);
394 let _: Q = &h * Q::from(42);
395 let _: Q = &i * Q::from(42);
396 let _: Q = &j * Q::from(42);
397 let _: Q = &k * Q::from(42);
398
399 let _: Q = Q::from(42) * &b;
400 let _: Q = Q::from(42) * &c;
401 let _: Q = Q::from(42) * &d;
402 let _: Q = Q::from(42) * &e;
403 let _: Q = Q::from(42) * &f;
404 let _: Q = Q::from(42) * &g;
405 let _: Q = Q::from(42) * &h;
406 let _: Q = Q::from(42) * &i;
407 let _: Q = Q::from(42) * &j;
408 let _: Q = Q::from(42) * &k;
409
410 let _: Q = b * &a;
411 let _: Q = c * &a;
412 let _: Q = d * &a;
413 let _: Q = e * &a;
414 let _: Q = f * &a;
415 let _: Q = g * &a;
416 let _: Q = h * &a;
417 let _: Q = i * &a;
418 let _: Q = j * &a;
419 let _: Q = k * &a;
420
421 let _: Q = Q::from(42) * b;
422 let _: Q = Q::from(42) * c;
423 let _: Q = Q::from(42) * d;
424 let _: Q = Q::from(42) * e;
425 let _: Q = Q::from(42) * f;
426 let _: Q = Q::from(42) * g;
427 let _: Q = Q::from(42) * h;
428 let _: Q = Q::from(42) * i;
429 let _: Q = Q::from(42) * j;
430 let _: Q = Q::from(42) * k;
431
432 let _: Q = b * Q::from(42);
433 let _: Q = c * Q::from(42);
434 let _: Q = d * Q::from(42);
435 let _: Q = e * Q::from(42);
436 let _: Q = f * Q::from(42);
437 let _: Q = g * Q::from(42);
438 let _: Q = h * Q::from(42);
439 let _: Q = i * Q::from(42);
440 let _: Q = j * Q::from(42);
441 let _: Q = k * Q::from(42);
442 }
443}