malachite_q/arithmetic/reciprocal.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Rational;
10use core::mem::swap;
11use malachite_base::num::arithmetic::traits::{Reciprocal, ReciprocalAssign};
12
13impl Reciprocal for Rational {
14 type Output = Self;
15
16 /// Reciprocates a [`Rational`], taking it by value.
17 ///
18 /// $$
19 /// f(x) = 1/x.
20 /// $$
21 ///
22 /// # Worst-case complexity
23 /// Constant time and additional memory.
24 ///
25 /// # Examples
26 /// ```
27 /// use malachite_base::num::arithmetic::traits::Reciprocal;
28 /// use malachite_q::Rational;
29 ///
30 /// assert_eq!(
31 /// Rational::from_signeds(22, 7).reciprocal().to_string(),
32 /// "7/22"
33 /// );
34 /// assert_eq!(
35 /// Rational::from_signeds(7, 22).reciprocal().to_string(),
36 /// "22/7"
37 /// );
38 /// ```
39 #[inline]
40 fn reciprocal(mut self) -> Self {
41 self.reciprocal_assign();
42 self
43 }
44}
45
46impl Reciprocal for &Rational {
47 type Output = Rational;
48
49 /// Reciprocates a [`Rational`], taking it by reference.
50 ///
51 /// $$
52 /// f(x) = 1/x.
53 /// $$
54 ///
55 /// # Worst-case complexity
56 /// $T(n) = O(n)$
57 ///
58 /// $M(n) = O(n)$
59 ///
60 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
61 ///
62 /// # Examples
63 /// ```
64 /// use malachite_base::num::arithmetic::traits::Reciprocal;
65 /// use malachite_q::Rational;
66 ///
67 /// assert_eq!(
68 /// (&Rational::from_signeds(22, 7)).reciprocal().to_string(),
69 /// "7/22"
70 /// );
71 /// assert_eq!(
72 /// (&Rational::from_signeds(7, 22)).reciprocal().to_string(),
73 /// "22/7"
74 /// );
75 /// ```
76 fn reciprocal(self) -> Rational {
77 assert_ne!(self.numerator, 0, "Cannot take reciprocal of zero");
78 Rational {
79 sign: self.sign,
80 numerator: self.denominator.clone(),
81 denominator: self.numerator.clone(),
82 }
83 }
84}
85
86impl ReciprocalAssign for Rational {
87 /// Reciprocates a [`Rational`] in place.
88 ///
89 /// $$
90 /// x \gets 1/x.
91 /// $$
92 ///
93 /// # Worst-case complexity
94 /// Constant time and additional memory.
95 ///
96 /// # Examples
97 /// ```
98 /// use malachite_base::num::arithmetic::traits::ReciprocalAssign;
99 /// use malachite_q::Rational;
100 ///
101 /// let mut x = Rational::from_signeds(22, 7);
102 /// x.reciprocal_assign();
103 /// assert_eq!(x.to_string(), "7/22");
104 ///
105 /// let mut x = Rational::from_signeds(7, 22);
106 /// x.reciprocal_assign();
107 /// assert_eq!(x.to_string(), "22/7");
108 /// ```
109 fn reciprocal_assign(&mut self) {
110 assert_ne!(self.numerator, 0, "Cannot take reciprocal of zero");
111 swap(&mut self.numerator, &mut self.denominator);
112 }
113}