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}