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}