malachite_float/conversion/
from_rational.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::InnerFloat::Finite;
10use crate::arithmetic::shl_round::shl_prec_round_assign_helper;
11use crate::arithmetic::shr_round::shr_prec_round_assign_helper;
12use crate::conversion::from_integer::{
13    from_integer_prec_round_zero_exponent, from_integer_zero_exponent,
14};
15use crate::conversion::from_natural::{
16    from_natural_prec_round_zero_exponent, from_natural_prec_round_zero_exponent_ref,
17    from_natural_zero_exponent, from_natural_zero_exponent_ref,
18};
19use crate::{Float, significand_bits};
20use core::cmp::Ordering::{self, *};
21use core::cmp::max;
22use malachite_base::num::arithmetic::traits::{
23    CheckedLogBase2, IsPowerOf2, NegAssign, NegModPowerOf2, RoundToMultipleOfPowerOf2, UnsignedAbs,
24};
25use malachite_base::num::basic::integers::PrimitiveInt;
26use malachite_base::num::basic::traits::{Infinity, NegativeInfinity, NegativeZero, Zero};
27use malachite_base::num::conversion::traits::{
28    ConvertibleFrom, ExactFrom, RoundingFrom, SaturatingFrom,
29};
30use malachite_base::num::logic::traits::SignificantBits;
31use malachite_base::rounding_modes::RoundingMode::{self, *};
32use malachite_nz::integer::Integer;
33use malachite_nz::platform::Limb;
34use malachite_q::Rational;
35use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
36
37pub_test! {from_rational_prec_round_direct(
38    x: Rational,
39    prec: u64,
40    rm: RoundingMode,
41) -> (Float, Ordering) {
42    assert_ne!(prec, 0);
43    let sign = x >= 0;
44    if let Some(pow) = x.denominator_ref().checked_log_base_2() {
45        let n = x.into_numerator();
46        let n_bits = n.significant_bits();
47        let (mut y, mut o) =
48            from_integer_prec_round_zero_exponent(Integer::from_sign_and_abs(sign, n), prec, rm);
49        o = shr_prec_round_assign_helper(&mut y, i128::from(pow) - i128::from(n_bits), prec, rm, o);
50        assert!(rm != Exact || o == Equal, "Inexact conversion from Rational to Float");
51        (y, o)
52    } else {
53        let mut exponent = i32::saturating_from(x.floor_log_base_2_abs());
54        if exponent >= Float::MAX_EXPONENT {
55            return match (sign, rm) {
56                (true, Up | Ceiling | Nearest) => (Float::INFINITY, Greater),
57                (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
58                (false, Up | Floor | Nearest) => (Float::NEGATIVE_INFINITY, Less),
59                (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
60                (_, Exact) => panic!("Inexact conversion from Rational to Float"),
61            };
62        }
63        let (significand, o) =
64            Integer::rounding_from(x << (i128::exact_from(prec) - i128::from(exponent) - 1), rm);
65        let sign = significand >= 0;
66        let mut significand = significand.unsigned_abs();
67        let away_from_0 = if sign { Greater } else { Less };
68        if o == away_from_0 && significand.is_power_of_2() {
69            exponent += 1;
70            if exponent >= Float::MAX_EXPONENT {
71                return if sign {
72                    (Float::INFINITY, Greater)
73                } else {
74                    (Float::NEGATIVE_INFINITY, Less)
75                };
76            }
77        }
78        exponent += 1;
79        if exponent < Float::MIN_EXPONENT {
80            assert!(rm != Exact, "Inexact conversion from Rational to Float");
81            return if rm == Nearest
82                && exponent == Float::MIN_EXPONENT - 1
83                && (o == away_from_0.reverse() || !significand.is_power_of_2())
84            {
85                if sign {
86                    (Float::min_positive_value_prec(prec), Greater)
87                } else {
88                    (-Float::min_positive_value_prec(prec), Less)
89                }
90            } else {
91                match (sign, rm) {
92                    (true, Up | Ceiling) => (Float::min_positive_value_prec(prec), Greater),
93                    (true, Floor | Down | Nearest) => (Float::ZERO, Less),
94                    (false, Up | Floor) => (-Float::min_positive_value_prec(prec), Less),
95                    (false, Ceiling | Down | Nearest) => (Float::NEGATIVE_ZERO, Greater),
96                    (_, Exact) => unreachable!(),
97                }
98            };
99        }
100        significand <<= significand
101            .significant_bits()
102            .neg_mod_power_of_2(Limb::LOG_WIDTH);
103        let target_bits = prec
104            .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
105            .0;
106        let current_bits = significand_bits(&significand);
107        if current_bits > target_bits {
108            significand >>= current_bits - target_bits;
109        }
110        (
111            Float(Finite {
112                sign,
113                exponent,
114                precision: prec,
115                significand,
116            }),
117            o,
118        )
119    }
120}}
121
122pub_test! {from_rational_prec_round_using_div(
123    x: Rational,
124    prec: u64,
125    mut rm: RoundingMode,
126) -> (Float, Ordering) {
127    let sign = x >= 0;
128    if !sign {
129        rm.neg_assign();
130    }
131    let (n, d) = x.into_numerator_and_denominator();
132    let is_zero = n == 0;
133    let (f, o) = match (
134        if is_zero {
135            None
136        } else {
137            n.checked_log_base_2()
138        },
139        d.checked_log_base_2(),
140    ) {
141        (Some(log_n), Some(log_d)) => Float::power_of_2_prec_round(
142            i64::saturating_from(i128::from(log_n) - i128::from(log_d)),
143            prec,
144            rm,
145        ),
146        (None, Some(log_d)) => {
147            let bits = n.significant_bits();
148            let (mut f, mut o) = from_natural_prec_round_zero_exponent(n, prec, rm);
149            o = shr_prec_round_assign_helper(
150                &mut f,
151                i128::from(log_d) - i128::from(bits),
152                prec,
153                rm,
154                o,
155            );
156            (f, o)
157        }
158        (Some(log_n), None) => {
159            let bits = d.significant_bits();
160            let (mut f, mut o) =
161                from_natural_zero_exponent(d).reciprocal_prec_round(prec, rm);
162            o = shl_prec_round_assign_helper(
163                &mut f,
164                i128::from(log_n) - i128::from(bits),
165                prec,
166                rm,
167                o,
168            );
169            (f, o)
170        }
171        (None, None) => {
172            let n_bits = n.significant_bits();
173            let d_bits = d.significant_bits();
174            let (mut f, mut o) = from_natural_zero_exponent(n).div_prec_round(
175                from_natural_zero_exponent(d),
176                prec,
177                rm,
178            );
179            o = shl_prec_round_assign_helper(
180                &mut f,
181                i128::from(n_bits) - i128::from(d_bits),
182                prec,
183                rm,
184                o,
185            );
186            (f, o)
187        }
188    };
189    if sign {
190        (f, o)
191    } else {
192        (-f, o.reverse())
193    }
194}}
195
196pub_test! {from_rational_prec_round_ref_direct(
197    x: &Rational,
198    prec: u64,
199    rm: RoundingMode,
200) -> (Float, Ordering) {
201    assert_ne!(prec, 0);
202    let sign = *x >= 0;
203    if let Some(pow) = x.denominator_ref().checked_log_base_2() {
204        let n = x.numerator_ref();
205        let n_bits = n.significant_bits();
206        let (mut y, mut o) =
207            from_natural_prec_round_zero_exponent_ref(n, prec, if sign { rm } else { -rm });
208        o = shr_prec_round_assign_helper(
209            &mut y,
210            i128::from(pow) - i128::from(n_bits),
211            prec,
212            if sign { rm } else { -rm },
213            o,
214        );
215        assert!(rm != Exact || o == Equal, "Inexact conversion from Rational to Float");
216        if sign {
217            (y, o)
218        } else {
219            (-y, o.reverse())
220        }
221    } else {
222        let mut exponent = i32::saturating_from(x.floor_log_base_2_abs());
223        if exponent >= Float::MAX_EXPONENT {
224            return match (sign, rm) {
225                (true, Up | Ceiling | Nearest) => (Float::INFINITY, Greater),
226                (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
227                (false, Up | Floor | Nearest) => (Float::NEGATIVE_INFINITY, Less),
228                (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
229                (_, Exact) => panic!("Inexact conversion from Rational to Float"),
230            };
231        }
232        let (significand, o) =
233            Integer::rounding_from(x << (i128::exact_from(prec) - i128::from(exponent) - 1), rm);
234        let sign = significand >= 0;
235        let mut significand = significand.unsigned_abs();
236        let away_from_0 = if sign { Greater } else { Less };
237        if o == away_from_0 && significand.is_power_of_2() {
238            exponent += 1;
239            if exponent >= Float::MAX_EXPONENT {
240                return if sign {
241                    (Float::INFINITY, Greater)
242                } else {
243                    (Float::NEGATIVE_INFINITY, Less)
244                };
245            }
246        }
247        exponent += 1;
248        if exponent < Float::MIN_EXPONENT {
249            assert!(rm != Exact, "Inexact conversion from Rational to Float");
250            return if rm == Nearest
251                && exponent == Float::MIN_EXPONENT - 1
252                && (o == away_from_0.reverse() || !significand.is_power_of_2())
253            {
254                if sign {
255                    (Float::min_positive_value_prec(prec), Greater)
256                } else {
257                    (-Float::min_positive_value_prec(prec), Less)
258                }
259            } else {
260                match (sign, rm) {
261                    (true, Up | Ceiling) => (Float::min_positive_value_prec(prec), Greater),
262                    (true, Floor | Down | Nearest) => (Float::ZERO, Less),
263                    (false, Up | Floor) => (-Float::min_positive_value_prec(prec), Less),
264                    (false, Ceiling | Down | Nearest) => (Float::NEGATIVE_ZERO, Greater),
265                    (_, Exact) => unreachable!(),
266                }
267            };
268        }
269        significand <<= significand
270            .significant_bits()
271            .neg_mod_power_of_2(Limb::LOG_WIDTH);
272        let target_bits = prec
273            .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
274            .0;
275        let current_bits = significand_bits(&significand);
276        if current_bits > target_bits {
277            significand >>= current_bits - target_bits;
278        }
279        (
280            Float(Finite {
281                sign,
282                exponent,
283                precision: prec,
284                significand,
285            }),
286            o,
287        )
288    }
289}}
290
291pub_test! {from_rational_prec_round_ref_using_div(
292    x: &Rational,
293    prec: u64,
294    mut rm: RoundingMode,
295) -> (Float, Ordering) {
296    let sign = *x >= 0;
297    if !sign {
298        rm.neg_assign();
299    }
300    let (n, d) = x.numerator_and_denominator_ref();
301    let is_zero = *n == 0;
302    let (f, o) = match (
303        if is_zero {
304            None
305        } else {
306            n.checked_log_base_2()
307        },
308        d.checked_log_base_2(),
309    ) {
310        (Some(log_n), Some(log_d)) => Float::power_of_2_prec_round(
311            i64::saturating_from(i128::from(log_n) - i128::from(log_d)),
312            prec,
313            rm,
314        ),
315        (None, Some(log_d)) => {
316            let (mut f, mut o) = from_natural_prec_round_zero_exponent_ref(n, prec, rm);
317            o = shr_prec_round_assign_helper(
318                &mut f,
319                i128::from(log_d) - i128::from(n.significant_bits()),
320                prec,
321                rm,
322                o,
323            );
324            (f, o)
325        }
326        (Some(log_n), None) => {
327            let (mut f, mut o) =
328                from_natural_zero_exponent_ref(d).reciprocal_prec_round(prec, rm);
329            o = shl_prec_round_assign_helper(
330                &mut f,
331                i128::from(log_n) - i128::from(d.significant_bits()),
332                prec,
333                rm,
334                o,
335            );
336            (f, o)
337        }
338        (None, None) => {
339            let (mut f, mut o) = from_natural_zero_exponent_ref(n).div_prec_round(
340                from_natural_zero_exponent_ref(d),
341                prec,
342                rm,
343            );
344            o = shl_prec_round_assign_helper(
345                &mut f,
346                i128::from(n.significant_bits()) - i128::from(d.significant_bits()),
347                prec,
348                rm,
349                o,
350            );
351            (f, o)
352        }
353    };
354    if sign {
355        (f, o)
356    } else {
357        (-f, o.reverse())
358    }
359}}
360
361const FROM_RATIONAL_THRESHOLD: u64 = 100;
362
363impl Float {
364    /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by value. If the [`Float`]
365    /// is nonzero, it has the specified precision. If rounding is needed, the specified rounding
366    /// mode is used. An [`Ordering`] is also returned, indicating whether the returned value is
367    /// less than, equal to, or greater than the original value.
368    ///
369    /// If you're only using [`Nearest`], try using [`Float::from_rational_prec`] instead.
370    ///
371    /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
372    ///   function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
373    ///   to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
374    /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
375    ///   function overflows to $-\infty$ if `rm` is `Floor`, `Up`, or `Nearest`, and rounds up to
376    ///   $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
377    /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
378    ///   underflows to positive zero if `rm` is `Floor` or `Down`, rounds up to $2^{-2^{30}}$ if
379    ///   `rm` is `Ceiling` or `Up`, underflows to positive zero if `rm` is `Nearest` and the
380    ///   [`Rational`] rounds to a value less than or equal to $2^{-2^{30}-1}$, and rounds up to
381    ///   $2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value greater than
382    ///   $2^{-2^{30}-1}$.
383    /// - If the [`Rational`] rounds to a negative value greater than $-2^{-2^{30}}$), this function
384    ///   underflows to negative zero if `rm` is `Ceiling` or `Down`, rounds down to $-2^{-2^{30}}$
385    ///   if `rm` is `Floor` or `Up`, underflows to negative zero if `rm` is `Nearest` and the
386    ///   [`Rational`] rounds to a value greater than or equal to $-2^{-2^{30}-1}$, and rounds down
387    ///   to $-2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value less than
388    ///   $-2^{-2^{30}-1}$.
389    ///
390    /// # Worst-case complexity
391    /// $T(n) = O(n)$
392    ///
393    /// $M(n) = O(n)$
394    ///
395    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(n.significant_bits(), prec)`.
396    ///
397    /// # Panics
398    /// Panics if `prec` is zero, or if `rm` is exact and the `Rational` cannot be exactly
399    /// represented with the specified precision.
400    ///
401    /// # Examples
402    /// ```
403    /// use malachite_base::rounding_modes::RoundingMode::*;
404    /// use malachite_float::Float;
405    /// use malachite_q::Rational;
406    /// use std::cmp::Ordering::*;
407    ///
408    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Floor);
409    /// assert_eq!(x.to_string(), "0.333");
410    /// assert_eq!(x.get_prec(), Some(10));
411    /// assert_eq!(o, Less);
412    ///
413    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Ceiling);
414    /// assert_eq!(x.to_string(), "0.3335");
415    /// assert_eq!(x.get_prec(), Some(10));
416    /// assert_eq!(o, Greater);
417    ///
418    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Nearest);
419    /// assert_eq!(x.to_string(), "0.3335");
420    /// assert_eq!(x.get_prec(), Some(10));
421    /// assert_eq!(o, Greater);
422    ///
423    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Floor);
424    /// assert_eq!(x.to_string(), "-0.3335");
425    /// assert_eq!(x.get_prec(), Some(10));
426    /// assert_eq!(o, Less);
427    ///
428    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Ceiling);
429    /// assert_eq!(x.to_string(), "-0.333");
430    /// assert_eq!(x.get_prec(), Some(10));
431    /// assert_eq!(o, Greater);
432    ///
433    /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Nearest);
434    /// assert_eq!(x.to_string(), "-0.3335");
435    /// assert_eq!(x.get_prec(), Some(10));
436    /// assert_eq!(o, Less);
437    /// ```
438    #[inline]
439    pub fn from_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
440        if max(x.significant_bits(), prec) < FROM_RATIONAL_THRESHOLD {
441            from_rational_prec_round_direct(x, prec, rm)
442        } else {
443            from_rational_prec_round_using_div(x, prec, rm)
444        }
445    }
446
447    /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by value. If the [`Float`]
448    /// is nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
449    /// whether the returned value is less than, equal to, or greater than the original value.
450    ///
451    /// If the [`Rational`] is dyadic (its denominator is a power of 2), then you can convert it to
452    /// a [`Float`] using `try_from` instead. The precision of the resulting [`Float`] will be the
453    /// number of significant bits of the [`Rational`]'s numerator.
454    ///
455    /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
456    /// as well as a precision, try [`Float::from_rational_prec_round`].
457    ///
458    /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
459    ///   function overflows to $\infty$.
460    /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
461    ///   function overflows to $-\infty$.
462    /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
463    ///   underflows to positive zero if the [`Rational`] rounds to a value less than or equal to
464    ///   $2^{-2^{30}-1}$ and rounds up to $2^{-2^{30}}$ if the [`Rational`] rounds to a value
465    ///   greater than $2^{-2^{30}-1}$.
466    /// - If the [`Rational`] rounds to a negative value greater than $2^{-2^{30}}$), this function
467    ///   underflows to negative zero if the [`Rational`] rounds to a value greater than or equal to
468    ///   $-2^{-2^{30}-1}$ and rounds down to $-2^{-2^{30}}$ if the [`Rational`] rounds to a value
469    ///   less than $-2^{-2^{30}-1}$.
470    ///
471    /// # Panics
472    /// Panics if `prec` is zero.
473    ///
474    /// # Worst-case complexity
475    /// $T(n) = O(n \log n \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(x.significant_bits(), prec)`.
480    ///
481    /// # Examples
482    /// ```
483    /// use malachite_base::num::basic::traits::Zero;
484    /// use malachite_float::Float;
485    /// use malachite_q::Rational;
486    /// use std::cmp::Ordering::*;
487    ///
488    /// let (x, o) = Float::from_rational_prec(Rational::ZERO, 10);
489    /// assert_eq!(x.to_string(), "0.0");
490    /// assert_eq!(o, Equal);
491    ///
492    /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(1, 3), 10);
493    /// assert_eq!(x.to_string(), "0.3335");
494    /// assert_eq!(x.get_prec(), Some(10));
495    /// assert_eq!(o, Greater);
496    ///
497    /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(1, 3), 100);
498    /// assert_eq!(x.to_string(), "0.3333333333333333333333333333335");
499    /// assert_eq!(x.get_prec(), Some(100));
500    /// assert_eq!(o, Greater);
501    ///
502    /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(-1, 3), 10);
503    /// assert_eq!(x.to_string(), "-0.3335");
504    /// assert_eq!(x.get_prec(), Some(10));
505    /// assert_eq!(o, Less);
506    ///
507    /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(-1, 3), 100);
508    /// assert_eq!(x.to_string(), "-0.3333333333333333333333333333335");
509    /// assert_eq!(x.get_prec(), Some(100));
510    /// assert_eq!(o, Less);
511    /// ```
512    #[inline]
513    pub fn from_rational_prec(x: Rational, prec: u64) -> (Float, Ordering) {
514        Float::from_rational_prec_round(x, prec, Nearest)
515    }
516
517    /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by reference. If the
518    /// [`Float`] is nonzero, it has the specified precision. If rounding is needed, the specified
519    /// rounding mode is used. An [`Ordering`] is also returned, indicating whether the returned
520    /// value is less than, equal to, or greater than the original value.
521    ///
522    /// If you're only using [`Nearest`], try using [`Float::from_rational_prec_ref`] instead.
523    ///
524    /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
525    ///   function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
526    ///   to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
527    /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
528    ///   function overflows to $-\infty$ if `rm` is `Floor`, `Up`, or `Nearest`, and rounds up to
529    ///   $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
530    /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
531    ///   underflows to positive zero if `rm` is `Floor` or `Down`, rounds up to $2^{-2^{30}}$ if
532    ///   `rm` is `Ceiling` or `Up`, underflows to positive zero if `rm` is `Nearest` and the
533    ///   [`Rational`] rounds to a value less than or equal to $2^{-2^{30}-1}$, and rounds up to
534    ///   $2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value greater than
535    ///   $2^{-2^{30}-1}$.
536    /// - If the [`Rational`] rounds to a negative value greater than $-2^{-2^{30}}$), this function
537    ///   underflows to negative zero if `rm` is `Ceiling` or `Down`, rounds down to $-2^{-2^{30}}$
538    ///   if `rm` is `Floor` or `Up`, underflows to negative zero if `rm` is `Nearest` and the
539    ///   [`Rational`] rounds to a value greater than or equal to $-2^{-2^{30}-1}$, and rounds down
540    ///   to $-2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value less than
541    ///   $-2^{-2^{30}-1}$.
542    ///
543    /// # Worst-case complexity
544    /// $T(n) = O(n \log n \log\log n)$
545    ///
546    /// $M(n) = O(n \log n)$
547    ///
548    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(), prec)`.
549    ///
550    /// # Panics
551    /// Panics if `prec` is zero, or if `rm` is exact and the `Rational` cannot be exactly
552    /// represented with the specified precision.
553    ///
554    /// # Examples
555    /// ```
556    /// use malachite_base::rounding_modes::RoundingMode::*;
557    /// use malachite_float::Float;
558    /// use malachite_q::Rational;
559    /// use std::cmp::Ordering::*;
560    ///
561    /// let (x, o) = Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Floor);
562    /// assert_eq!(x.to_string(), "0.333");
563    /// assert_eq!(x.get_prec(), Some(10));
564    /// assert_eq!(o, Less);
565    ///
566    /// let (x, o) =
567    ///     Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Ceiling);
568    /// assert_eq!(x.to_string(), "0.3335");
569    /// assert_eq!(x.get_prec(), Some(10));
570    /// assert_eq!(o, Greater);
571    ///
572    /// let (x, o) =
573    ///     Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Nearest);
574    /// assert_eq!(x.to_string(), "0.3335");
575    /// assert_eq!(x.get_prec(), Some(10));
576    /// assert_eq!(o, Greater);
577    ///
578    /// let (x, o) = Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Floor);
579    /// assert_eq!(x.to_string(), "-0.3335");
580    /// assert_eq!(x.get_prec(), Some(10));
581    /// assert_eq!(o, Less);
582    ///
583    /// let (x, o) =
584    ///     Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Ceiling);
585    /// assert_eq!(x.to_string(), "-0.333");
586    /// assert_eq!(x.get_prec(), Some(10));
587    /// assert_eq!(o, Greater);
588    ///
589    /// let (x, o) =
590    ///     Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Nearest);
591    /// assert_eq!(x.to_string(), "-0.3335");
592    /// assert_eq!(x.get_prec(), Some(10));
593    /// assert_eq!(o, Less);
594    /// ```
595    #[inline]
596    pub fn from_rational_prec_round_ref(
597        x: &Rational,
598        prec: u64,
599        rm: RoundingMode,
600    ) -> (Float, Ordering) {
601        if max(x.significant_bits(), prec) < FROM_RATIONAL_THRESHOLD {
602            from_rational_prec_round_ref_direct(x, prec, rm)
603        } else {
604            from_rational_prec_round_ref_using_div(x, prec, rm)
605        }
606    }
607
608    /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by reference. If the
609    /// [`Float`] is nonzero, it has the specified precision. An [`Ordering`] is also returned,
610    /// indicating whether the returned value is less than, equal to, or greater than the original
611    /// value.
612    ///
613    /// If the [`Rational`] is dyadic (its denominator is a power of 2), then you can convert it to
614    /// a [`Float`] using `try_from` instead. The precision of the resulting [`Float`] will be the
615    /// number of significant bits of the [`Rational`]'s numerator.
616    ///
617    /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
618    /// as well as a precision, try [`Float::from_rational_prec_round_ref`].
619    ///
620    /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
621    ///   function overflows to $\infty$.
622    /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
623    ///   function overflows to $-\infty$.
624    /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
625    ///   underflows to positive zero if the [`Rational`] rounds to a value less than or equal to
626    ///   $2^{-2^{30}-1}$ and rounds up to $2^{-2^{30}}$ if the [`Rational`] rounds to a value
627    ///   greater than $2^{-2^{30}-1}$.
628    /// - If the [`Rational`] rounds to a negative value greater than $2^{-2^{30}}$), this function
629    ///   underflows to negative zero if the [`Rational`] rounds to a value greater than or equal to
630    ///   $-2^{-2^{30}-1}$ and rounds down to $-2^{-2^{30}}$ if the [`Rational`] rounds to a value
631    ///   less than $-2^{-2^{30}-1}$.
632    ///
633    /// # Worst-case complexity
634    /// $T(n) = O(n \log n \log\log n)$
635    ///
636    /// $M(n) = O(n \log n)$
637    ///
638    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(), prec)`.
639    ///
640    /// # Panics
641    /// Panics if `prec` is zero.
642    ///
643    /// # Examples
644    /// ```
645    /// use malachite_base::num::basic::traits::Zero;
646    /// use malachite_float::Float;
647    /// use malachite_q::Rational;
648    /// use std::cmp::Ordering::*;
649    ///
650    /// let (x, o) = Float::from_rational_prec_ref(&Rational::ZERO, 10);
651    /// assert_eq!(x.to_string(), "0.0");
652    /// assert_eq!(o, Equal);
653    ///
654    /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(1, 3), 10);
655    /// assert_eq!(x.to_string(), "0.3335");
656    /// assert_eq!(x.get_prec(), Some(10));
657    /// assert_eq!(o, Greater);
658    ///
659    /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(1, 3), 100);
660    /// assert_eq!(x.to_string(), "0.3333333333333333333333333333335");
661    /// assert_eq!(x.get_prec(), Some(100));
662    /// assert_eq!(o, Greater);
663    ///
664    /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(-1, 3), 10);
665    /// assert_eq!(x.to_string(), "-0.3335");
666    /// assert_eq!(x.get_prec(), Some(10));
667    /// assert_eq!(o, Less);
668    ///
669    /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(-1, 3), 100);
670    /// assert_eq!(x.to_string(), "-0.3333333333333333333333333333335");
671    /// assert_eq!(x.get_prec(), Some(100));
672    /// assert_eq!(o, Less);
673    /// ```
674    #[inline]
675    pub fn from_rational_prec_ref(x: &Rational, prec: u64) -> (Float, Ordering) {
676        Float::from_rational_prec_round_ref(x, prec, Nearest)
677    }
678}
679
680impl TryFrom<Rational> for Float {
681    type Error = FloatConversionError;
682
683    /// Converts a [`Rational`] to an [`Float`], taking the [`Rational`] by value. If the
684    /// [`Rational`]'s denominator is not a power of 2, or if the [`Rational`] is too far from zero
685    /// or too close to zero to be represented as a [`Float`], an error is returned.
686    ///
687    /// The [`Float`]'s precision is the minimum number of bits needed to exactly represent the
688    /// [`Rational`].
689    ///
690    /// - If the [`Rational`] is greater than or equal to $2^{2^{30}-1}$), this function returns an
691    ///   overflow error.
692    /// - If the [`Rational`] is less than or equal to $-2^{2^{30}-1}$), this function returns an
693    ///   overflow error.
694    /// - If the [`Rational`] is positive and less than $2^{-2^{30}}$), this function returns an
695    ///   underflow error.
696    /// - If the [`Rational`] is negative and greater than $-2^{-2^{30}}$), this function returns an
697    ///   underflow error.
698    ///
699    /// # Worst-case complexity
700    /// $T(n) = O(n)$
701    ///
702    /// $M(n) = O(1)$
703    ///
704    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
705    ///
706    /// # Examples
707    /// ```
708    /// use malachite_base::num::basic::traits::Zero;
709    /// use malachite_float::Float;
710    /// use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
711    /// use malachite_q::Rational;
712    ///
713    /// assert_eq!(Float::try_from(Rational::ZERO).unwrap(), 0);
714    /// assert_eq!(
715    ///     Float::try_from(Rational::from_signeds(1, 8)).unwrap(),
716    ///     0.125
717    /// );
718    /// assert_eq!(
719    ///     Float::try_from(Rational::from_signeds(-1, 8)).unwrap(),
720    ///     -0.125
721    /// );
722    ///
723    /// assert_eq!(
724    ///     Float::try_from(Rational::from_signeds(1, 3)),
725    ///     Err(FloatConversionError::Inexact)
726    /// );
727    /// assert_eq!(
728    ///     Float::try_from(Rational::from_signeds(-1, 3)),
729    ///     Err(FloatConversionError::Inexact)
730    /// );
731    /// ```
732    fn try_from(x: Rational) -> Result<Float, Self::Error> {
733        if x == 0u32 {
734            return Ok(Float::ZERO);
735        }
736        if let Some(log_denominator) = x.denominator_ref().checked_log_base_2() {
737            let exponent = i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1);
738            if exponent > Float::MAX_EXPONENT {
739                return Err(FloatConversionError::Overflow);
740            } else if exponent < Float::MIN_EXPONENT {
741                return Err(FloatConversionError::Underflow);
742            }
743            let n = Integer::from_sign_and_abs(x >= 0u32, x.into_numerator());
744            let n_bits = n.significant_bits();
745            Ok(from_integer_zero_exponent(n) >> (i128::from(log_denominator) - i128::from(n_bits)))
746        } else {
747            Err(FloatConversionError::Inexact)
748        }
749    }
750}
751
752impl TryFrom<&Rational> for Float {
753    type Error = FloatConversionError;
754
755    /// Converts a [`Rational`] to an [`Float`], taking the [`Rational`] by reference. If the
756    /// [`Rational`]'s denominator is not a power of 2, or if the [`Rational`] is too far from zero
757    /// or too close to zero to be represented as a [`Float`], an error is returned.
758    ///
759    /// The [`Float`]'s precision is the minimum number of bits needed to exactly represent the
760    /// [`Rational`].
761    ///
762    /// - If the [`Rational`] is greater than or equal to $2^{2^{30}-1}$), this function returns an
763    ///   overflow error.
764    /// - If the [`Rational`] is less than or equal to $-2^{2^{30}-1}$), this function returns an
765    ///   overflow error.
766    /// - If the [`Rational`] is positive and less than $2^{-2^{30}}$), this function returns an
767    ///   underflow error.
768    /// - If the [`Rational`] is negative and greater than $-2^{-2^{30}}$), this function returns an
769    ///   underflow error.
770    ///
771    /// # Worst-case complexity
772    /// $T(n) = O(n)$
773    ///
774    /// $M(n) = O(n)$
775    ///
776    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
777    ///
778    /// # Examples
779    /// ```
780    /// use malachite_base::num::basic::traits::Zero;
781    /// use malachite_float::Float;
782    /// use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
783    /// use malachite_q::Rational;
784    ///
785    /// assert_eq!(Float::try_from(&Rational::ZERO).unwrap(), 0);
786    /// assert_eq!(
787    ///     Float::try_from(&Rational::from_signeds(1, 8)).unwrap(),
788    ///     0.125
789    /// );
790    /// assert_eq!(
791    ///     Float::try_from(&Rational::from_signeds(-1, 8)).unwrap(),
792    ///     -0.125
793    /// );
794    ///
795    /// assert_eq!(
796    ///     Float::try_from(&Rational::from_signeds(1, 3)),
797    ///     Err(FloatConversionError::Inexact)
798    /// );
799    /// assert_eq!(
800    ///     Float::try_from(&Rational::from_signeds(-1, 3)),
801    ///     Err(FloatConversionError::Inexact)
802    /// );
803    /// ```
804    fn try_from(x: &Rational) -> Result<Float, Self::Error> {
805        if *x == 0u32 {
806            return Ok(Float::ZERO);
807        }
808        if let Some(log_denominator) = x.denominator_ref().checked_log_base_2() {
809            let exponent = i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1);
810            if exponent > Float::MAX_EXPONENT {
811                return Err(FloatConversionError::Overflow);
812            } else if exponent < Float::MIN_EXPONENT {
813                return Err(FloatConversionError::Underflow);
814            }
815            let n = x.numerator_ref();
816            let n_bits = n.significant_bits();
817            let mut n = from_natural_zero_exponent_ref(n);
818            if *x < 0 {
819                n.neg_assign();
820            }
821            Ok(n >> (i128::from(log_denominator) - i128::from(n_bits)))
822        } else {
823            Err(FloatConversionError::Inexact)
824        }
825    }
826}
827
828impl ConvertibleFrom<&Rational> for Float {
829    /// Determines whether a [`Rational`] can be converted to an [`Float`], taking the [`Rational`]
830    /// by reference.
831    ///
832    /// The [`Rational`]s that are convertible to [`Float`]s are precisely those whose denominators
833    /// are powers of two, and would not overflow or underflow.
834    ///
835    /// # Worst-case complexity
836    /// $T(n) = O(n)$
837    ///
838    /// $M(n) = O(1)$
839    ///
840    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
841    ///
842    /// # Examples
843    /// ```
844    /// use malachite_base::num::basic::traits::Zero;
845    /// use malachite_base::num::conversion::traits::ConvertibleFrom;
846    /// use malachite_float::Float;
847    /// use malachite_q::Rational;
848    ///
849    /// assert_eq!(Float::convertible_from(&Rational::ZERO), true);
850    /// assert_eq!(Float::convertible_from(&Rational::from_signeds(3, 8)), true);
851    /// assert_eq!(
852    ///     Float::convertible_from(&Rational::from_signeds(-3, 8)),
853    ///     true
854    /// );
855    ///
856    /// assert_eq!(
857    ///     Float::convertible_from(&Rational::from_signeds(1, 3)),
858    ///     false
859    /// );
860    /// assert_eq!(
861    ///     Float::convertible_from(&Rational::from_signeds(-1, 3)),
862    ///     false
863    /// );
864    /// ```
865    #[inline]
866    fn convertible_from(x: &Rational) -> bool {
867        *x == 0
868            || x.denominator_ref().is_power_of_2()
869                && (Float::MIN_EXPONENT..=Float::MAX_EXPONENT)
870                    .contains(&i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1))
871    }
872}