malachite_q/conversion/
from_numerator_and_denominator.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 malachite_base::num::arithmetic::traits::{DivExact, Gcd, UnsignedAbs};
11use malachite_base::num::basic::signeds::PrimitiveSigned;
12use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
13use malachite_nz::integer::Integer;
14use malachite_nz::natural::Natural;
15use malachite_nz::platform::{Limb, SignedLimb};
16
17macro_rules! const_gcd_step {
18    ($x: ident, $y: ident) => {
19        let new_y = $x % $y;
20        $x = $y;
21        $y = new_y;
22        if $y == 0 {
23            return $x;
24        }
25    };
26}
27
28// Worst case when Limb = u64 is const_gcd(Fib_92, Fib_93) = const_gcd(7540113804746346429,
29// 12200160415121876738)
30const fn const_gcd(mut x: Limb, mut y: Limb) -> Limb {
31    if y == 0 {
32        x
33    } else {
34        const_gcd_step!(x, y);
35        const_gcd_step!(x, y);
36        const_gcd_step!(x, y);
37        const_gcd_step!(x, y);
38        const_gcd_step!(x, y);
39        const_gcd_step!(x, y);
40        const_gcd_step!(x, y);
41        const_gcd_step!(x, y);
42        const_gcd_step!(x, y);
43        const_gcd_step!(x, y);
44        const_gcd_step!(x, y);
45        const_gcd_step!(x, y);
46        const_gcd_step!(x, y);
47        const_gcd_step!(x, y);
48        const_gcd_step!(x, y);
49        const_gcd_step!(x, y);
50        const_gcd_step!(x, y);
51        const_gcd_step!(x, y);
52        const_gcd_step!(x, y);
53        const_gcd_step!(x, y);
54        const_gcd_step!(x, y);
55        const_gcd_step!(x, y);
56        const_gcd_step!(x, y);
57        const_gcd_step!(x, y);
58        const_gcd_step!(x, y);
59        const_gcd_step!(x, y);
60        const_gcd_step!(x, y);
61        const_gcd_step!(x, y);
62        const_gcd_step!(x, y);
63        const_gcd_step!(x, y);
64        const_gcd_step!(x, y);
65        const_gcd_step!(x, y);
66        const_gcd_step!(x, y);
67        const_gcd_step!(x, y);
68        const_gcd_step!(x, y);
69        const_gcd_step!(x, y);
70        const_gcd_step!(x, y);
71        const_gcd_step!(x, y);
72        const_gcd_step!(x, y);
73        const_gcd_step!(x, y);
74        const_gcd_step!(x, y);
75        const_gcd_step!(x, y);
76        const_gcd_step!(x, y);
77        const_gcd_step!(x, y);
78        const_gcd_step!(x, y);
79        const_gcd_step!(x, y);
80        const_gcd_step!(x, y);
81        const_gcd_step!(x, y);
82        const_gcd_step!(x, y);
83        const_gcd_step!(x, y);
84        const_gcd_step!(x, y);
85        const_gcd_step!(x, y);
86        const_gcd_step!(x, y);
87        const_gcd_step!(x, y);
88        const_gcd_step!(x, y);
89        const_gcd_step!(x, y);
90        const_gcd_step!(x, y);
91        const_gcd_step!(x, y);
92        const_gcd_step!(x, y);
93        const_gcd_step!(x, y);
94        const_gcd_step!(x, y);
95        const_gcd_step!(x, y);
96        const_gcd_step!(x, y);
97        const_gcd_step!(x, y);
98        const_gcd_step!(x, y);
99        const_gcd_step!(x, y);
100        const_gcd_step!(x, y);
101        const_gcd_step!(x, y);
102        const_gcd_step!(x, y);
103        const_gcd_step!(x, y);
104        const_gcd_step!(x, y);
105        const_gcd_step!(x, y);
106        const_gcd_step!(x, y);
107        const_gcd_step!(x, y);
108        const_gcd_step!(x, y);
109        const_gcd_step!(x, y);
110        const_gcd_step!(x, y);
111        const_gcd_step!(x, y);
112        const_gcd_step!(x, y);
113        const_gcd_step!(x, y);
114        const_gcd_step!(x, y);
115        const_gcd_step!(x, y);
116        const_gcd_step!(x, y);
117        const_gcd_step!(x, y);
118        const_gcd_step!(x, y);
119        const_gcd_step!(x, y);
120        const_gcd_step!(x, y);
121        const_gcd_step!(x, y);
122        const_gcd_step!(x, y);
123        const_gcd_step!(x, y);
124        const_gcd_step!(x, y);
125        const_gcd_step!(x, y);
126        unreachable!()
127    }
128}
129
130impl Rational {
131    /// Converts two[`Limb`](crate#limbs)s, representing a numerator and a denominator, to a
132    /// [`Rational`].
133    ///
134    /// If `denominator` is zero, `None` is returned.
135    ///
136    /// This function is const, so it may be used to define constants. When called at runtime, it is
137    /// slower than [`Rational::from_unsigneds`].
138    ///
139    /// # Worst-case complexity
140    /// $T(n) = O(n^2)$
141    ///
142    /// $M(n) = O(n)$
143    ///
144    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
145    /// denominator.significant_bits())`.
146    ///
147    /// # Examples
148    /// ```
149    /// use malachite_q::Rational;
150    ///
151    /// const TWO_THIRDS: Rational = Rational::const_from_unsigneds(2, 3);
152    /// assert_eq!(TWO_THIRDS, Rational::from_unsigneds(2u32, 3));
153    ///
154    /// const TWO_THIRDS_ALT: Rational = Rational::const_from_unsigneds(22, 33);
155    /// assert_eq!(TWO_THIRDS_ALT, Rational::from_unsigneds(2u32, 3));
156    /// ```
157    pub const fn const_from_unsigneds(numerator: Limb, denominator: Limb) -> Self {
158        assert!(denominator != 0);
159        let gcd = const_gcd(numerator, denominator);
160        Self {
161            sign: true,
162            numerator: Natural::const_from(numerator / gcd),
163            denominator: Natural::const_from(denominator / gcd),
164        }
165    }
166
167    /// Converts two[`SignedLimb`](crate#limbs)s, representing a numerator and a denominator, to a
168    /// [`Rational`].
169    ///
170    /// If `denominator` is zero, `None` is returned.
171    ///
172    /// This function is const, so it may be used to define constants. When called at runtime, it is
173    /// slower than [`Rational::from_signeds`].
174    ///
175    /// # Worst-case complexity
176    /// $T(n) = O(n^2)$
177    ///
178    /// $M(n) = O(n)$
179    ///
180    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
181    /// denominator.significant_bits())`.
182    ///
183    /// # Examples
184    /// ```
185    /// use malachite_q::Rational;
186    ///
187    /// const NEGATIVE_TWO_THIRDS: Rational = Rational::const_from_signeds(-2, 3);
188    /// assert_eq!(NEGATIVE_TWO_THIRDS, Rational::from_signeds(-2, 3));
189    ///
190    /// const NEGATIVE_TWO_THIRDS_ALT: Rational = Rational::const_from_signeds(-22, 33);
191    /// assert_eq!(NEGATIVE_TWO_THIRDS_ALT, Rational::from_signeds(-2, 3));
192    /// ```
193    pub const fn const_from_signeds(numerator: SignedLimb, denominator: SignedLimb) -> Self {
194        assert!(denominator != 0);
195        let sign = numerator == 0 || (numerator > 0) == (denominator > 0);
196        let numerator = numerator.unsigned_abs();
197        let denominator = denominator.unsigned_abs();
198        let gcd = const_gcd(numerator, denominator);
199        Self {
200            sign,
201            numerator: Natural::const_from(numerator / gcd),
202            denominator: Natural::const_from(denominator / gcd),
203        }
204    }
205
206    /// Converts two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by value.
207    ///
208    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator. Only non-negative
209    /// [`Rational`]s can be produced with this function.
210    ///
211    /// The denominator may not be zero.
212    ///
213    /// The input [`Natural`]s may have common factors; this function reduces them.
214    ///
215    /// # Worst-case complexity
216    /// $T(n) = O(n (\log n)^2 \log\log n)$
217    ///
218    /// $M(n) = O(n \log n)$
219    ///
220    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
221    /// denominator.significant_bits())`.
222    ///
223    /// # Panics
224    /// Panics if `denominator` is zero.
225    ///
226    /// # Examples
227    /// ```
228    /// use malachite_base::num::basic::traits::Zero;
229    /// use malachite_nz::natural::Natural;
230    /// use malachite_q::Rational;
231    ///
232    /// assert_eq!(
233    ///     Rational::from_naturals(Natural::from(4u32), Natural::from(6u32)).to_string(),
234    ///     "2/3"
235    /// );
236    /// assert_eq!(
237    ///     Rational::from_naturals(Natural::ZERO, Natural::from(6u32)),
238    ///     0
239    /// );
240    /// ```
241    pub fn from_naturals(numerator: Natural, denominator: Natural) -> Self {
242        assert_ne!(denominator, 0);
243        let gcd = (&numerator).gcd(&denominator);
244        Self {
245            sign: true,
246            numerator: numerator.div_exact(&gcd),
247            denominator: denominator.div_exact(gcd),
248        }
249    }
250
251    /// Converts two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by reference.
252    ///
253    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator. Only non-negative
254    /// [`Rational`]s can be produced with this function.
255    ///
256    /// The denominator may not be zero.
257    ///
258    /// The input [`Natural`]s may have common factors; this function reduces them.
259    ///
260    /// # Worst-case complexity
261    /// $T(n) = O(n (\log n)^2 \log\log n)$
262    ///
263    /// $M(n) = O(n \log n)$
264    ///
265    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
266    /// denominator.significant_bits())`.
267    ///
268    /// # Panics
269    /// Panics if `denominator` is zero.
270    ///
271    /// # Examples
272    /// ```
273    /// use malachite_base::num::basic::traits::Zero;
274    /// use malachite_nz::natural::Natural;
275    /// use malachite_q::Rational;
276    ///
277    /// assert_eq!(
278    ///     Rational::from_naturals_ref(&Natural::from(4u32), &Natural::from(6u32)).to_string(),
279    ///     "2/3"
280    /// );
281    /// assert_eq!(
282    ///     Rational::from_naturals_ref(&Natural::ZERO, &Natural::from(6u32)),
283    ///     0
284    /// );
285    /// ```
286    pub fn from_naturals_ref(numerator: &Natural, denominator: &Natural) -> Self {
287        assert_ne!(*denominator, 0);
288        let gcd = numerator.gcd(denominator);
289        Self {
290            sign: true,
291            numerator: numerator.div_exact(&gcd),
292            denominator: denominator.div_exact(gcd),
293        }
294    }
295
296    /// Converts two unsigned primitive integers to a [`Rational`].
297    ///
298    /// The integers become the [`Rational`]'s numerator and denominator. Only non-negative
299    /// [`Rational`]s can be produced with this function.
300    ///
301    /// The denominator may not be zero.
302    ///
303    /// The input integers may have common factors; this function reduces them.
304    ///
305    /// # Worst-case complexity
306    /// $T(n) = O(n^2)$
307    ///
308    /// $M(n) = O(n)$
309    ///
310    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
311    /// denominator.significant_bits())`.
312    ///
313    /// # Panics
314    /// Panics if `denominator` is zero.
315    ///
316    /// # Examples
317    /// ```
318    /// use malachite_q::Rational;
319    ///
320    /// assert_eq!(Rational::from_unsigneds(4u32, 6).to_string(), "2/3");
321    /// assert_eq!(Rational::from_unsigneds(0u32, 6), 0);
322    /// ```
323    #[inline]
324    pub fn from_unsigneds<T: PrimitiveUnsigned>(numerator: T, denominator: T) -> Self
325    where
326        Natural: From<T>,
327    {
328        Self::from_naturals(Natural::from(numerator), Natural::from(denominator))
329    }
330
331    /// Converts two [`Integer`]s to a [`Rational`], taking the [`Integer`]s by value.
332    ///
333    /// The absolute values of the [`Integer`]s become the [`Rational`]'s numerator and denominator.
334    /// The sign of the [`Rational`] is the sign of the [`Integer`]s' quotient.
335    ///
336    /// The denominator may not be zero.
337    ///
338    /// The input [`Integer`]s may have common factors; this function reduces them.
339    ///
340    /// # Worst-case complexity
341    /// $T(n) = O(n (\log n)^2 \log\log n)$
342    ///
343    /// $M(n) = O(n \log n)$
344    ///
345    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
346    /// denominator.significant_bits())`.
347    ///
348    /// # Panics
349    /// Panics if `denominator` is zero.
350    ///
351    /// # Examples
352    /// ```
353    /// use malachite_base::num::basic::traits::Zero;
354    /// use malachite_nz::integer::Integer;
355    /// use malachite_q::Rational;
356    ///
357    /// assert_eq!(
358    ///     Rational::from_integers(Integer::from(4), Integer::from(6)).to_string(),
359    ///     "2/3"
360    /// );
361    /// assert_eq!(
362    ///     Rational::from_integers(Integer::from(4), Integer::from(-6)).to_string(),
363    ///     "-2/3"
364    /// );
365    /// assert_eq!(Rational::from_integers(Integer::ZERO, Integer::from(6)), 0);
366    /// assert_eq!(Rational::from_integers(Integer::ZERO, Integer::from(-6)), 0);
367    /// ```
368    pub fn from_integers(numerator: Integer, denominator: Integer) -> Self {
369        assert_ne!(denominator, 0);
370        let sign = numerator == 0 || ((numerator > 0) == (denominator > 0));
371        let mut q = Self::from_naturals(numerator.unsigned_abs(), denominator.unsigned_abs());
372        q.sign = sign;
373        q
374    }
375
376    /// Converts two [`Integer`]s to a [`Rational`], taking the [`Integer`]s by reference.
377    ///
378    /// The absolute values of the [`Integer`]s become the [`Rational`]'s numerator and denominator.
379    /// The sign of the [`Rational`] is the sign of the [`Integer`]s' quotient.
380    ///
381    /// The denominator may not be zero.
382    ///
383    /// The input [`Integer`]s may have common factors; this function reduces them.
384    ///
385    /// # Worst-case complexity
386    /// $T(n) = O(n (\log n)^2 \log\log n)$
387    ///
388    /// $M(n) = O(n \log n)$
389    ///
390    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
391    /// denominator.significant_bits())`.
392    ///
393    /// # Panics
394    /// Panics if `denominator` is zero.
395    ///
396    /// # Examples
397    /// ```
398    /// use malachite_base::num::basic::traits::Zero;
399    /// use malachite_nz::integer::Integer;
400    /// use malachite_q::Rational;
401    ///
402    /// assert_eq!(
403    ///     Rational::from_integers_ref(&Integer::from(4), &Integer::from(6)).to_string(),
404    ///     "2/3"
405    /// );
406    /// assert_eq!(
407    ///     Rational::from_integers_ref(&Integer::from(4), &Integer::from(-6)).to_string(),
408    ///     "-2/3"
409    /// );
410    /// assert_eq!(
411    ///     Rational::from_integers_ref(&Integer::ZERO, &Integer::from(6)),
412    ///     0
413    /// );
414    /// assert_eq!(
415    ///     Rational::from_integers_ref(&Integer::ZERO, &Integer::from(-6)),
416    ///     0
417    /// );
418    /// ```
419    pub fn from_integers_ref(numerator: &Integer, denominator: &Integer) -> Self {
420        assert_ne!(*denominator, 0);
421        let mut q =
422            Self::from_naturals_ref(numerator.unsigned_abs_ref(), denominator.unsigned_abs_ref());
423        q.sign = *numerator == 0 || ((*numerator > 0) == (*denominator > 0));
424        q
425    }
426
427    /// Converts two signed primitive integers to a [`Rational]`.
428    ///
429    /// The absolute values of the integers become the [`Rational`]'s numerator and denominator. The
430    /// sign of the [`Rational`] is the sign of the integers' quotient.
431    ///
432    /// The denominator may not be zero.
433    ///
434    /// The input integers may have common factors; this function reduces them.
435    ///
436    /// # Worst-case complexity
437    /// $T(n) = O(n^2)$
438    ///
439    /// $M(n) = O(n)$
440    ///
441    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
442    /// denominator.significant_bits())`.
443    ///
444    /// # Panics
445    /// Panics if `denominator` is zero.
446    ///
447    /// # Examples
448    /// ```
449    /// use malachite_q::Rational;
450    ///
451    /// assert_eq!(Rational::from_signeds(4i8, 6).to_string(), "2/3");
452    /// assert_eq!(Rational::from_signeds(4i8, -6).to_string(), "-2/3");
453    /// assert_eq!(Rational::from_signeds(0i8, 6), 0);
454    /// assert_eq!(Rational::from_signeds(0i8, -6), 0);
455    /// ```
456    #[inline]
457    pub fn from_signeds<T: PrimitiveSigned>(numerator: T, denominator: T) -> Self
458    where
459        Integer: From<T>,
460    {
461        Self::from_integers(Integer::from(numerator), Integer::from(denominator))
462    }
463
464    /// Converts a sign and two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by value.
465    ///
466    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator, and the sign indicates
467    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
468    /// [`Rational`] will be non-negative regardless of the sign.
469    ///
470    /// The denominator may not be zero.
471    ///
472    /// The input [`Natural`]s may have common factors; this function reduces them.
473    ///
474    /// # Worst-case complexity
475    /// $T(n) = O(n (\log n)^2 \log\log n)$
476    ///
477    /// $M(n) = O(n \log n)$
478    ///
479    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
480    /// denominator.significant_bits())`.
481    ///
482    /// # Panics
483    /// Panics if `denominator` is zero.
484    ///
485    /// # Examples
486    /// ```
487    /// use malachite_nz::natural::Natural;
488    /// use malachite_q::Rational;
489    ///
490    /// assert_eq!(
491    ///     Rational::from_sign_and_naturals(true, Natural::from(4u32), Natural::from(6u32))
492    ///         .to_string(),
493    ///     "2/3"
494    /// );
495    /// assert_eq!(
496    ///     Rational::from_sign_and_naturals(false, Natural::from(4u32), Natural::from(6u32))
497    ///         .to_string(),
498    ///     "-2/3"
499    /// );
500    /// ```
501    pub fn from_sign_and_naturals(sign: bool, numerator: Natural, denominator: Natural) -> Self {
502        assert_ne!(denominator, 0);
503        let gcd = (&numerator).gcd(&denominator);
504        Self {
505            sign: sign || numerator == 0,
506            numerator: numerator.div_exact(&gcd),
507            denominator: denominator.div_exact(gcd),
508        }
509    }
510
511    /// Converts a sign and two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by
512    /// reference.
513    ///
514    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator, and the sign indicates
515    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
516    /// [`Rational`] will be non-negative regardless of the sign.
517    ///
518    /// The denominator may not be zero.
519    ///
520    /// The input [`Natural`]s may have common factors; this function reduces them.
521    ///
522    /// # Worst-case complexity
523    /// $T(n) = O(n (\log n)^2 \log\log n)$
524    ///
525    /// $M(n) = O(n \log n)$
526    ///
527    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
528    /// denominator.significant_bits())`.
529    ///
530    /// # Panics
531    /// Panics if `denominator` is zero.
532    ///
533    /// # Examples
534    /// ```
535    /// use malachite_nz::natural::Natural;
536    /// use malachite_q::Rational;
537    ///
538    /// assert_eq!(
539    ///     Rational::from_sign_and_naturals_ref(true, &Natural::from(4u32), &Natural::from(6u32))
540    ///         .to_string(),
541    ///     "2/3"
542    /// );
543    /// assert_eq!(
544    ///     Rational::from_sign_and_naturals_ref(false, &Natural::from(4u32), &Natural::from(6u32))
545    ///         .to_string(),
546    ///     "-2/3"
547    /// );
548    /// ```
549    pub fn from_sign_and_naturals_ref(
550        sign: bool,
551        numerator: &Natural,
552        denominator: &Natural,
553    ) -> Self {
554        assert_ne!(*denominator, 0);
555        let gcd = numerator.gcd(denominator);
556        Self {
557            sign: sign || *numerator == 0,
558            numerator: numerator.div_exact(&gcd),
559            denominator: denominator.div_exact(gcd),
560        }
561    }
562
563    /// Converts a sign and two primitive unsigned integers to a [`Rational`].
564    ///
565    /// The integers become the [`Rational`]'s numerator and denominator, and the sign indicates
566    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
567    /// [`Rational`] will be non-negative regardless of the sign.
568    ///
569    /// The denominator may not be zero.
570    ///
571    /// The input integers may have common factors; this function reduces them.
572    ///
573    /// # Worst-case complexity
574    /// $T(n) = O(n^2)$
575    ///
576    /// $M(n) = O(n)$
577    ///
578    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
579    /// denominator.significant_bits())`.
580    ///
581    /// # Panics
582    /// Panics if `denominator` is zero.
583    ///
584    /// # Examples
585    /// ```
586    /// use malachite_q::Rational;
587    ///
588    /// assert_eq!(
589    ///     Rational::from_sign_and_unsigneds(true, 4u32, 6).to_string(),
590    ///     "2/3"
591    /// );
592    /// assert_eq!(
593    ///     Rational::from_sign_and_unsigneds(false, 4u32, 6).to_string(),
594    ///     "-2/3"
595    /// );
596    /// ```
597    pub fn from_sign_and_unsigneds<T: PrimitiveUnsigned>(
598        sign: bool,
599        numerator: T,
600        denominator: T,
601    ) -> Self
602    where
603        Natural: From<T>,
604    {
605        Self::from_sign_and_naturals(sign, Natural::from(numerator), Natural::from(denominator))
606    }
607}