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) -> Rational {
158        assert!(denominator != 0);
159        let gcd = const_gcd(numerator, denominator);
160        Rational {
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) -> Rational {
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        Rational {
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) -> Rational {
242        assert_ne!(denominator, 0);
243        let gcd = (&numerator).gcd(&denominator);
244        Rational {
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) -> Rational {
287        assert_ne!(*denominator, 0);
288        let gcd = numerator.gcd(denominator);
289        Rational {
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) -> Rational
325    where
326        Natural: From<T>,
327    {
328        Rational::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) -> Rational {
369        assert_ne!(denominator, 0);
370        let sign = numerator == 0 || ((numerator > 0) == (denominator > 0));
371        let mut q = Rational::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) -> Rational {
420        assert_ne!(*denominator, 0);
421        let mut q = Rational::from_naturals_ref(
422            numerator.unsigned_abs_ref(),
423            denominator.unsigned_abs_ref(),
424        );
425        q.sign = *numerator == 0 || ((*numerator > 0) == (*denominator > 0));
426        q
427    }
428
429    /// Converts two signed primitive integers to a [`Rational]`.
430    ///
431    /// The absolute values of the integers become the [`Rational`]'s numerator and denominator. The
432    /// sign of the [`Rational`] is the sign of the integers' quotient.
433    ///
434    /// The denominator may not be zero.
435    ///
436    /// The input integers may have common factors; this function reduces them.
437    ///
438    /// # Worst-case complexity
439    /// $T(n) = O(n^2)$
440    ///
441    /// $M(n) = O(n)$
442    ///
443    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
444    /// denominator.significant_bits())`.
445    ///
446    /// # Panics
447    /// Panics if `denominator` is zero.
448    ///
449    /// # Examples
450    /// ```
451    /// use malachite_q::Rational;
452    ///
453    /// assert_eq!(Rational::from_signeds(4i8, 6).to_string(), "2/3");
454    /// assert_eq!(Rational::from_signeds(4i8, -6).to_string(), "-2/3");
455    /// assert_eq!(Rational::from_signeds(0i8, 6), 0);
456    /// assert_eq!(Rational::from_signeds(0i8, -6), 0);
457    /// ```
458    #[inline]
459    pub fn from_signeds<T: PrimitiveSigned>(numerator: T, denominator: T) -> Rational
460    where
461        Integer: From<T>,
462    {
463        Rational::from_integers(Integer::from(numerator), Integer::from(denominator))
464    }
465
466    /// Converts a sign and two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by value.
467    ///
468    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator, and the sign indicates
469    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
470    /// [`Rational`] will be non-negative regardless of the sign.
471    ///
472    /// The denominator may not be zero.
473    ///
474    /// The input [`Natural`]s may have common factors; this function reduces them.
475    ///
476    /// # Worst-case complexity
477    /// $T(n) = O(n (\log n)^2 \log\log n)$
478    ///
479    /// $M(n) = O(n \log n)$
480    ///
481    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
482    /// denominator.significant_bits())`.
483    ///
484    /// # Panics
485    /// Panics if `denominator` is zero.
486    ///
487    /// # Examples
488    /// ```
489    /// use malachite_nz::natural::Natural;
490    /// use malachite_q::Rational;
491    ///
492    /// assert_eq!(
493    ///     Rational::from_sign_and_naturals(true, Natural::from(4u32), Natural::from(6u32))
494    ///         .to_string(),
495    ///     "2/3"
496    /// );
497    /// assert_eq!(
498    ///     Rational::from_sign_and_naturals(false, Natural::from(4u32), Natural::from(6u32))
499    ///         .to_string(),
500    ///     "-2/3"
501    /// );
502    /// ```
503    pub fn from_sign_and_naturals(
504        sign: bool,
505        numerator: Natural,
506        denominator: Natural,
507    ) -> Rational {
508        assert_ne!(denominator, 0);
509        let gcd = (&numerator).gcd(&denominator);
510        Rational {
511            sign: sign || numerator == 0,
512            numerator: numerator.div_exact(&gcd),
513            denominator: denominator.div_exact(gcd),
514        }
515    }
516
517    /// Converts a sign and two [`Natural`]s to a [`Rational`], taking the [`Natural`]s by
518    /// reference.
519    ///
520    /// The [`Natural`]s become the [`Rational`]'s numerator and denominator, and the sign indicates
521    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
522    /// [`Rational`] will be non-negative regardless of the sign.
523    ///
524    /// The denominator may not be zero.
525    ///
526    /// The input [`Natural`]s may have common factors; this function reduces them.
527    ///
528    /// # Worst-case complexity
529    /// $T(n) = O(n (\log n)^2 \log\log n)$
530    ///
531    /// $M(n) = O(n \log n)$
532    ///
533    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
534    /// denominator.significant_bits())`.
535    ///
536    /// # Panics
537    /// Panics if `denominator` is zero.
538    ///
539    /// # Examples
540    /// ```
541    /// use malachite_nz::natural::Natural;
542    /// use malachite_q::Rational;
543    ///
544    /// assert_eq!(
545    ///     Rational::from_sign_and_naturals_ref(true, &Natural::from(4u32), &Natural::from(6u32))
546    ///         .to_string(),
547    ///     "2/3"
548    /// );
549    /// assert_eq!(
550    ///     Rational::from_sign_and_naturals_ref(false, &Natural::from(4u32), &Natural::from(6u32))
551    ///         .to_string(),
552    ///     "-2/3"
553    /// );
554    /// ```
555    pub fn from_sign_and_naturals_ref(
556        sign: bool,
557        numerator: &Natural,
558        denominator: &Natural,
559    ) -> Rational {
560        assert_ne!(*denominator, 0);
561        let gcd = numerator.gcd(denominator);
562        Rational {
563            sign: sign || *numerator == 0,
564            numerator: numerator.div_exact(&gcd),
565            denominator: denominator.div_exact(gcd),
566        }
567    }
568
569    /// Converts a sign and two primitive unsigned integers to a [`Rational`].
570    ///
571    /// The integers become the [`Rational`]'s numerator and denominator, and the sign indicates
572    /// whether the [`Rational`] should be non-negative. If the numerator is zero, then the
573    /// [`Rational`] will be non-negative regardless of the sign.
574    ///
575    /// The denominator may not be zero.
576    ///
577    /// The input integers may have common factors; this function reduces them.
578    ///
579    /// # Worst-case complexity
580    /// $T(n) = O(n^2)$
581    ///
582    /// $M(n) = O(n)$
583    ///
584    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(numerator.significant_bits(),
585    /// denominator.significant_bits())`.
586    ///
587    /// # Panics
588    /// Panics if `denominator` is zero.
589    ///
590    /// # Examples
591    /// ```
592    /// use malachite_q::Rational;
593    ///
594    /// assert_eq!(
595    ///     Rational::from_sign_and_unsigneds(true, 4u32, 6).to_string(),
596    ///     "2/3"
597    /// );
598    /// assert_eq!(
599    ///     Rational::from_sign_and_unsigneds(false, 4u32, 6).to_string(),
600    ///     "-2/3"
601    /// );
602    /// ```
603    pub fn from_sign_and_unsigneds<T: PrimitiveUnsigned>(
604        sign: bool,
605        numerator: T,
606        denominator: T,
607    ) -> Rational
608    where
609        Natural: From<T>,
610    {
611        Rational::from_sign_and_naturals(sign, Natural::from(numerator), Natural::from(denominator))
612    }
613}