malachite_float/conversion/
from_natural.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::Float;
10use crate::InnerFloat::Finite;
11use core::cmp::Ordering::{self, *};
12use malachite_base::num::arithmetic::traits::{
13    DivisibleByPowerOf2, FloorLogBase2, ModPowerOf2, NegModPowerOf2, PowerOf2,
14    RoundToMultipleOfPowerOf2Assign, SaturatingSubAssign,
15};
16use malachite_base::num::basic::integers::PrimitiveInt;
17use malachite_base::num::basic::traits::{Infinity, Zero};
18use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, SaturatingFrom};
19use malachite_base::num::logic::traits::{BitAccess, SignificantBits};
20use malachite_base::rounding_modes::RoundingMode::{self, *};
21use malachite_nz::natural::{Natural, bit_to_limb_count_ceiling};
22use malachite_nz::platform::Limb;
23use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
24
25fn from_natural_prec_round_helper(
26    x: &Natural,
27    prec: u64,
28    rm: RoundingMode,
29    bits: u64,
30) -> (Float, Ordering) {
31    if *x == 0 {
32        return (Float::ZERO, Equal);
33    }
34    let mut exponent = i32::saturating_from(bits);
35    if exponent > Float::MAX_EXPONENT {
36        return match rm {
37            Up | Ceiling | Nearest => (Float::INFINITY, Greater),
38            Floor | Down => (Float::max_finite_value_with_prec(prec), Less),
39            Exact => panic!("Inexact conversion from Natural to Float"),
40        };
41    }
42    let mut needed_bits = prec;
43    let sig_bits_in_highest_limb = bits.mod_power_of_2(Limb::LOG_WIDTH);
44    let mut needed_limbs = 1;
45    needed_bits.saturating_sub_assign(sig_bits_in_highest_limb);
46    if needed_bits != 0 {
47        needed_limbs += bit_to_limb_count_ceiling(needed_bits);
48    }
49    let mut rev_limbs = x.limbs().rev();
50    let mut significand = Natural::from_owned_limbs_desc(
51        (&mut rev_limbs)
52            .take(usize::exact_from(needed_limbs))
53            .collect(),
54    );
55    significand <<= significand
56        .significant_bits()
57        .neg_mod_power_of_2(Limb::LOG_WIDTH);
58    let mut mask_width = significand.significant_bits() - prec;
59    let mut erased_limb = 0;
60    if mask_width >= Limb::WIDTH {
61        erased_limb = significand.limbs()[0];
62        significand >>= Limb::WIDTH;
63        mask_width -= Limb::WIDTH;
64    }
65    let o = match rm {
66        Exact => {
67            let inexact = erased_limb != 0
68                || !significand.divisible_by_power_of_2(mask_width)
69                || rev_limbs.any(|y| y != 0);
70            assert!(!inexact, "Inexact conversion from Natural");
71            Equal
72        }
73        Floor | Down => {
74            let inexact = erased_limb != 0
75                || !significand.divisible_by_power_of_2(mask_width)
76                || rev_limbs.any(|y| y != 0);
77            if inexact {
78                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
79                Less
80            } else {
81                Equal
82            }
83        }
84        Ceiling | Up => {
85            let inexact = erased_limb != 0
86                || !significand.divisible_by_power_of_2(mask_width)
87                || rev_limbs.any(|y| y != 0);
88            if inexact {
89                let original_limb_count = significand.limb_count();
90                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
91                significand += Natural::power_of_2(mask_width);
92                if significand.limb_count() > original_limb_count {
93                    if exponent == Float::MAX_EXPONENT {
94                        return (Float::INFINITY, Greater);
95                    }
96                    significand >>= 1;
97                    exponent += 1;
98                }
99                Greater
100            } else {
101                Equal
102            }
103        }
104        Nearest => {
105            let half_bit = x.get_bit(bits - prec - 1);
106            let inexact_after_half = !x.divisible_by_power_of_2(bits - prec - 1);
107            let inexact = half_bit || inexact_after_half;
108            if half_bit && (inexact_after_half || x.get_bit(bits - prec)) {
109                let original_limb_count = significand.limb_count();
110                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
111                significand += Natural::power_of_2(mask_width);
112                if significand.limb_count() > original_limb_count {
113                    if exponent == Float::MAX_EXPONENT {
114                        return (Float::INFINITY, Greater);
115                    }
116                    significand >>= 1;
117                    exponent += 1;
118                }
119                Greater
120            } else if inexact {
121                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
122                Less
123            } else {
124                Equal
125            }
126        }
127    };
128    (
129        Float(Finite {
130            sign: true,
131            exponent,
132            precision: prec,
133            significand,
134        }),
135        o,
136    )
137}
138
139fn from_natural_prec_round_helper_zero_exponent(
140    x: &Natural,
141    prec: u64,
142    rm: RoundingMode,
143    bits: u64,
144) -> (Float, Ordering) {
145    let mut needed_bits = prec;
146    let sig_bits_in_highest_limb = bits.mod_power_of_2(Limb::LOG_WIDTH);
147    let mut needed_limbs = 1;
148    needed_bits.saturating_sub_assign(sig_bits_in_highest_limb);
149    if needed_bits != 0 {
150        needed_limbs += bit_to_limb_count_ceiling(needed_bits);
151    }
152    let mut rev_limbs = x.limbs().rev();
153    let mut significand =
154        Natural::from_owned_limbs_desc((&mut rev_limbs).take(needed_limbs).collect());
155    significand <<= significand
156        .significant_bits()
157        .neg_mod_power_of_2(Limb::LOG_WIDTH);
158    let mut mask_width = significand.significant_bits() - prec;
159    let mut erased_limb = 0;
160    if mask_width >= Limb::WIDTH {
161        erased_limb = significand.limbs()[0];
162        significand >>= Limb::WIDTH;
163        mask_width -= Limb::WIDTH;
164    }
165    let mut exponent = 0;
166    let o = match rm {
167        Exact => {
168            let inexact = erased_limb != 0
169                || !significand.divisible_by_power_of_2(mask_width)
170                || rev_limbs.any(|y| y != 0);
171            assert!(!inexact, "Inexact conversion from Natural");
172            Equal
173        }
174        Floor | Down => {
175            let inexact = erased_limb != 0
176                || !significand.divisible_by_power_of_2(mask_width)
177                || rev_limbs.any(|y| y != 0);
178            if inexact {
179                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
180                Less
181            } else {
182                Equal
183            }
184        }
185        Ceiling | Up => {
186            let inexact = erased_limb != 0
187                || !significand.divisible_by_power_of_2(mask_width)
188                || rev_limbs.any(|y| y != 0);
189            if inexact {
190                let original_limb_count = significand.limb_count();
191                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
192                significand += Natural::power_of_2(mask_width);
193                if significand.limb_count() > original_limb_count {
194                    significand >>= 1;
195                    exponent += 1;
196                }
197                Greater
198            } else {
199                Equal
200            }
201        }
202        Nearest => {
203            let half_bit = x.get_bit(bits - prec - 1);
204            let inexact_after_half = !x.divisible_by_power_of_2(bits - prec - 1);
205            let inexact = half_bit || inexact_after_half;
206            if half_bit && (inexact_after_half || x.get_bit(bits - prec)) {
207                let original_limb_count = significand.limb_count();
208                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
209                significand += Natural::power_of_2(mask_width);
210                if significand.limb_count() > original_limb_count {
211                    significand >>= 1;
212                    exponent += 1;
213                }
214                Greater
215            } else if inexact {
216                significand.round_to_multiple_of_power_of_2_assign(mask_width, Floor);
217                Less
218            } else {
219                Equal
220            }
221        }
222    };
223    (
224        Float(Finite {
225            sign: true,
226            exponent,
227            precision: prec,
228            significand,
229        }),
230        o,
231    )
232}
233
234fn from_natural_prec_round_helper_no_round_zero_exponent(
235    x: &Natural,
236    prec: u64,
237    bits: u64,
238) -> Float {
239    let mut needed_bits = prec;
240    let sig_bits_in_highest_limb = bits.mod_power_of_2(Limb::LOG_WIDTH);
241    let mut needed_limbs = 1;
242    needed_bits.saturating_sub_assign(sig_bits_in_highest_limb);
243    if needed_bits != 0 {
244        needed_limbs += bit_to_limb_count_ceiling(needed_bits);
245    }
246    let mut rev_limbs = x.limbs().rev();
247    let mut significand =
248        Natural::from_owned_limbs_desc((&mut rev_limbs).take(needed_limbs).collect());
249    significand <<= significand
250        .significant_bits()
251        .neg_mod_power_of_2(Limb::LOG_WIDTH);
252    if significand.significant_bits() - prec >= Limb::WIDTH {
253        significand >>= Limb::WIDTH;
254    }
255    Float(Finite {
256        sign: true,
257        exponent: 0,
258        precision: prec,
259        significand,
260    })
261}
262
263pub(crate) fn from_natural_prec_round_zero_exponent(
264    x: Natural,
265    prec: u64,
266    rm: RoundingMode,
267) -> (Float, Ordering) {
268    assert_ne!(prec, 0);
269    if x == 0u32 {
270        return (Float::ZERO, Equal);
271    }
272    let bits = x.significant_bits();
273    let mut f = Float(Finite {
274        sign: true,
275        exponent: 0,
276        precision: bits,
277        significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
278    });
279    let o = f.set_prec_round(prec, rm);
280    (f, o)
281}
282
283pub(crate) fn from_natural_prec_round_zero_exponent_ref(
284    x: &Natural,
285    prec: u64,
286    rm: RoundingMode,
287) -> (Float, Ordering) {
288    assert_ne!(prec, 0);
289    if *x == 0u32 {
290        return (Float::ZERO, Equal);
291    }
292    let bits = x.significant_bits();
293    if bits <= prec {
294        let mut f = Float(Finite {
295            sign: true,
296            exponent: 0,
297            precision: bits,
298            significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
299        });
300        let o = f.set_prec_round(prec, rm);
301        (f, o)
302    } else {
303        from_natural_prec_round_helper_zero_exponent(x, prec, rm, bits)
304    }
305}
306
307pub(crate) fn from_natural_zero_exponent(x: Natural) -> Float {
308    if x == 0 {
309        Float::ZERO
310    } else {
311        let bits = x.significant_bits();
312        let prec = bits - x.trailing_zeros().unwrap();
313        from_natural_prec_round_zero_exponent(x, prec, Floor).0
314    }
315}
316
317pub(crate) fn from_natural_zero_exponent_ref(x: &Natural) -> Float {
318    if *x == 0 {
319        Float::ZERO
320    } else {
321        let bits = x.significant_bits();
322        let prec = bits - x.trailing_zeros().unwrap();
323        from_natural_prec_round_helper_no_round_zero_exponent(x, prec, bits)
324    }
325}
326
327impl Float {
328    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by value. If the [`Float`] is
329    /// nonzero, it has the specified precision. If rounding is needed, the specified rounding mode
330    /// is used. An [`Ordering`] is also returned, indicating whether the returned value is less
331    /// than, equal to, or greater than the original value.
332    ///
333    /// If you're only using [`Nearest`], try using [`Float::from_natural_prec`] instead.
334    ///
335    /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
336    ///   function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
337    ///   to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
338    ///
339    /// # Worst-case complexity
340    /// $T(m,n) = O(\max(m,n))$
341    ///
342    /// $M(n) = O(n)$
343    ///
344    /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
345    /// `prec`.
346    ///
347    /// # Panics
348    /// Panics if `prec` is zero, or if `rm` is exact and the `Natural` cannot be exactly
349    /// represented with the specified precision.
350    ///
351    /// # Examples
352    /// ```
353    /// use malachite_base::num::basic::traits::Zero;
354    /// use malachite_base::rounding_modes::RoundingMode::*;
355    /// use malachite_float::Float;
356    /// use malachite_nz::natural::Natural;
357    /// use std::cmp::Ordering::*;
358    ///
359    /// let (x, o) = Float::from_natural_prec_round(Natural::ZERO, 10, Exact);
360    /// assert_eq!(x.to_string(), "0.0");
361    /// assert_eq!(o, Equal);
362    ///
363    /// let (x, o) = Float::from_natural_prec_round(Natural::from(123u32), 20, Exact);
364    /// assert_eq!(x.to_string(), "123.0");
365    /// assert_eq!(x.get_prec(), Some(20));
366    /// assert_eq!(o, Equal);
367    ///
368    /// let (x, o) = Float::from_natural_prec_round(Natural::from(123u32), 4, Floor);
369    /// assert_eq!(x.to_string(), "1.2e2");
370    /// assert_eq!(x.get_prec(), Some(4));
371    /// assert_eq!(o, Less);
372    ///
373    /// let (x, o) = Float::from_natural_prec_round(Natural::from(123u32), 4, Ceiling);
374    /// assert_eq!(x.to_string(), "1.3e2");
375    /// assert_eq!(x.get_prec(), Some(4));
376    /// assert_eq!(o, Greater);
377    /// ```
378    #[inline]
379    pub fn from_natural_prec_round(x: Natural, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
380        assert_ne!(prec, 0);
381        if x == 0u32 {
382            return (Self::ZERO, Equal);
383        }
384        let bits = x.significant_bits();
385        let bits_i32 = i32::saturating_from(bits);
386        if bits_i32 <= Self::MAX_EXPONENT {
387            let mut f = Self(Finite {
388                sign: true,
389                exponent: bits_i32,
390                precision: bits,
391                significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
392            });
393            let o = f.set_prec_round(prec, rm);
394            return (f, o);
395        }
396        match rm {
397            Up | Ceiling | Nearest => (Self::INFINITY, Greater),
398            Floor | Down => (Self::max_finite_value_with_prec(prec), Less),
399            Exact => panic!("Inexact conversion from Natural to Float"),
400        }
401    }
402
403    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference. If the [`Float`]
404    /// is nonzero, it has the specified precision. If rounding is needed, the specified rounding
405    /// mode is used. An [`Ordering`] is also returned, indicating whether the returned value is
406    /// less than, equal to, or greater than the original value.
407    ///
408    /// If you're only using [`Nearest`], try using [`Float::from_natural_prec_ref`] instead.
409    ///
410    /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
411    ///   function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
412    ///   to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
413    ///
414    /// # Worst-case complexity
415    /// $T(m,n) = O(\max(m,n))$
416    ///
417    /// $M(n) = O(n)$
418    ///
419    /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
420    /// `prec`.
421    ///
422    /// # Panics
423    /// Panics if `prec` is zero, or if `rm` is exact and the `Natural` cannot be exactly
424    /// represented with the specified precision.
425    ///
426    /// # Examples
427    /// ```
428    /// use malachite_base::num::basic::traits::Zero;
429    /// use malachite_base::rounding_modes::RoundingMode::*;
430    /// use malachite_float::Float;
431    /// use malachite_nz::natural::Natural;
432    /// use std::cmp::Ordering::*;
433    ///
434    /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::ZERO, 10, Exact);
435    /// assert_eq!(x.to_string(), "0.0");
436    /// assert_eq!(o, Equal);
437    ///
438    /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 20, Exact);
439    /// assert_eq!(x.to_string(), "123.0");
440    /// assert_eq!(x.get_prec(), Some(20));
441    /// assert_eq!(o, Equal);
442    ///
443    /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 4, Floor);
444    /// assert_eq!(x.to_string(), "1.2e2");
445    /// assert_eq!(x.get_prec(), Some(4));
446    /// assert_eq!(o, Less);
447    ///
448    /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 4, Ceiling);
449    /// assert_eq!(x.to_string(), "1.3e2");
450    /// assert_eq!(x.get_prec(), Some(4));
451    /// assert_eq!(o, Greater);
452    /// ```
453    #[inline]
454    pub fn from_natural_prec_round_ref(
455        x: &Natural,
456        prec: u64,
457        rm: RoundingMode,
458    ) -> (Self, Ordering) {
459        assert_ne!(prec, 0);
460        if *x == 0u32 {
461            return (Self::ZERO, Equal);
462        }
463        let bits = x.significant_bits();
464        if bits <= prec {
465            let bits_i32 = i32::saturating_from(bits);
466            if bits_i32 <= Self::MAX_EXPONENT {
467                let mut f = Self(Finite {
468                    sign: true,
469                    exponent: bits_i32,
470                    precision: bits,
471                    significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
472                });
473                let o = f.set_prec_round(prec, rm);
474                return (f, o);
475            }
476            match rm {
477                Up | Ceiling | Nearest => (Self::INFINITY, Greater),
478                Floor | Down => (Self::max_finite_value_with_prec(prec), Less),
479                Exact => panic!("Inexact conversion from Natural to Float"),
480            }
481        } else {
482            from_natural_prec_round_helper(x, prec, rm, bits)
483        }
484    }
485
486    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by value. If the [`Float`] is
487    /// nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
488    /// whether the returned value is less than, equal to, or greater than the original value.
489    ///
490    /// If you want the [`Float`]'s precision to be equal to the [`Natural`]'s number of significant
491    /// bits, try just using `Float::try_from` instead.
492    ///
493    /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
494    /// as well as a precision, try [`Float::from_natural_prec_round`].
495    ///
496    /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
497    ///   function overflows to $\infty$.
498    ///
499    /// # Worst-case complexity
500    /// $T(m,n) = O(\max(m,n))$
501    ///
502    /// $M(n) = O(n)$
503    ///
504    /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
505    /// `prec`.
506    ///
507    /// # Panics
508    /// Panics if `prec` is zero.
509    ///
510    /// # Examples
511    /// ```
512    /// use malachite_base::num::basic::traits::Zero;
513    /// use malachite_float::Float;
514    /// use malachite_nz::natural::Natural;
515    /// use std::cmp::Ordering::*;
516    ///
517    /// let (x, o) = Float::from_natural_prec(Natural::ZERO, 10);
518    /// assert_eq!(x.to_string(), "0.0");
519    /// assert_eq!(o, Equal);
520    ///
521    /// let (x, o) = Float::from_natural_prec(Natural::from(123u32), 20);
522    /// assert_eq!(x.to_string(), "123.0");
523    /// assert_eq!(x.get_prec(), Some(20));
524    /// assert_eq!(o, Equal);
525    ///
526    /// let (x, o) = Float::from_natural_prec(Natural::from(123u32), 4);
527    /// assert_eq!(x.to_string(), "1.2e2");
528    /// assert_eq!(x.get_prec(), Some(4));
529    /// assert_eq!(o, Less);
530    /// ```
531    #[inline]
532    pub fn from_natural_prec(x: Natural, prec: u64) -> (Self, Ordering) {
533        Self::from_natural_prec_round(x, prec, Nearest)
534    }
535
536    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference. If the [`Float`]
537    /// is nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
538    /// whether the returned value is less than, equal to, or greater than the original value.
539    ///
540    /// If you want the [`Float`]'s precision to be equal to the [`Natural`]'s number of significant
541    /// bits, try just using `Float::try_from` instead.
542    ///
543    /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
544    /// as well as a precision, try [`Float::from_natural_prec_round_ref`].
545    ///
546    /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
547    ///   function overflows to $\infty$.
548    ///
549    /// # Worst-case complexity
550    /// $T(m,n) = O(\max(m,n))$
551    ///
552    /// $M(n) = O(n)$
553    ///
554    /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
555    /// `prec`.
556    ///
557    /// # Panics
558    /// Panics if `prec` is zero.
559    ///
560    /// # Examples
561    /// ```
562    /// use malachite_base::num::basic::traits::Zero;
563    /// use malachite_float::Float;
564    /// use malachite_nz::natural::Natural;
565    /// use std::cmp::Ordering::*;
566    ///
567    /// let (x, o) = Float::from_natural_prec_ref(&Natural::ZERO, 10);
568    /// assert_eq!(x.to_string(), "0.0");
569    /// assert_eq!(o, Equal);
570    ///
571    /// let (x, o) = Float::from_natural_prec_ref(&Natural::from(123u32), 20);
572    /// assert_eq!(x.to_string(), "123.0");
573    /// assert_eq!(x.get_prec(), Some(20));
574    /// assert_eq!(o, Equal);
575    ///
576    /// let (x, o) = Float::from_natural_prec_ref(&Natural::from(123u32), 4);
577    /// assert_eq!(x.to_string(), "1.2e2");
578    /// assert_eq!(x.get_prec(), Some(4));
579    /// assert_eq!(o, Less);
580    /// ```
581    #[inline]
582    pub fn from_natural_prec_ref(x: &Natural, prec: u64) -> (Self, Ordering) {
583        Self::from_natural_prec_round_ref(x, prec, Nearest)
584    }
585}
586
587impl TryFrom<Natural> for Float {
588    type Error = FloatConversionError;
589
590    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by value.
591    ///
592    /// If the [`Natural`] is nonzero, the precision of the [`Float`] is the minimum possible
593    /// precision to represent the [`Natural`] exactly. If you want to specify some other precision,
594    /// try [`Float::from_natural_prec`]. This may require rounding, which uses [`Nearest`] by
595    /// default. To specify a rounding mode as well as a precision, try
596    /// [`Float::from_natural_prec_round`].
597    ///
598    /// If the [`Natural`] is greater than or equal to $2^{2^{30}-1}$, this function returns an
599    /// overflow error.
600    ///
601    /// # Worst-case complexity
602    /// $T(n) = O(n)$
603    ///
604    /// $M(n) = O(1)$
605    ///
606    /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
607    ///
608    /// # Examples
609    /// ```
610    /// use malachite_base::num::basic::traits::Zero;
611    /// use malachite_float::Float;
612    /// use malachite_nz::natural::Natural;
613    ///
614    /// assert_eq!(Float::try_from(Natural::ZERO).unwrap().to_string(), "0.0");
615    /// assert_eq!(
616    ///     Float::try_from(Natural::from(123u32)).unwrap().to_string(),
617    ///     "123.0"
618    /// );
619    /// assert_eq!(
620    ///     Float::try_from(Natural::from(123u32)).unwrap().get_prec(),
621    ///     Some(7)
622    /// );
623    /// assert_eq!(
624    ///     Float::try_from(Natural::from(10u32)).unwrap().to_string(),
625    ///     "10.0"
626    /// );
627    /// assert_eq!(
628    ///     Float::try_from(Natural::from(10u32)).unwrap().get_prec(),
629    ///     Some(3)
630    /// );
631    /// ```
632    fn try_from(x: Natural) -> Result<Self, Self::Error> {
633        if x == 0 {
634            Ok(Self::ZERO)
635        } else {
636            let bits = x.significant_bits();
637            let prec = bits - x.trailing_zeros().unwrap();
638            let (f, o) = Self::from_natural_prec_round(x, prec, Floor);
639            if o == Equal {
640                Ok(f)
641            } else {
642                Err(FloatConversionError::Overflow)
643            }
644        }
645    }
646}
647
648impl TryFrom<&Natural> for Float {
649    type Error = FloatConversionError;
650
651    /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference.
652    ///
653    /// If the [`Natural`] is nonzero, the precision of the [`Float`] is the minimum possible
654    /// precision to represent the [`Natural`] exactly. If you want to specify some other precision,
655    /// try [`Float::from_natural_prec`]. This may require rounding, which uses [`Nearest`] by
656    /// default. To specify a rounding mode as well as a precision, try
657    /// [`Float::from_natural_prec_round`].
658    ///
659    /// If the [`Natural`] is greater than or equal to $2^{2^{30}-1}$, this function returns an
660    /// overflow error.
661    ///
662    /// # Worst-case complexity
663    /// $T(n) = O(n)$
664    ///
665    /// $M(n) = O(n)$
666    ///
667    /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
668    ///
669    /// # Examples
670    /// ```
671    /// use malachite_base::num::basic::traits::Zero;
672    /// use malachite_float::Float;
673    /// use malachite_nz::natural::Natural;
674    ///
675    /// assert_eq!(Float::try_from(&Natural::ZERO).unwrap().to_string(), "0.0");
676    /// assert_eq!(
677    ///     Float::try_from(&Natural::from(123u32)).unwrap().to_string(),
678    ///     "123.0"
679    /// );
680    /// assert_eq!(
681    ///     Float::try_from(&Natural::from(123u32)).unwrap().get_prec(),
682    ///     Some(7)
683    /// );
684    /// assert_eq!(
685    ///     Float::try_from(&Natural::from(10u32)).unwrap().to_string(),
686    ///     "10.0"
687    /// );
688    /// assert_eq!(
689    ///     Float::try_from(&Natural::from(10u32)).unwrap().get_prec(),
690    ///     Some(3)
691    /// );
692    /// ```
693    #[inline]
694    fn try_from(x: &Natural) -> Result<Self, Self::Error> {
695        if *x == 0 {
696            Ok(Self::ZERO)
697        } else {
698            let bits = x.significant_bits();
699            let prec = bits - x.trailing_zeros().unwrap();
700            let (f, o) = Self::from_natural_prec_round_ref(x, prec, Floor);
701            if o == Equal {
702                Ok(f)
703            } else {
704                Err(FloatConversionError::Overflow)
705            }
706        }
707    }
708}
709
710impl ConvertibleFrom<&Natural> for Float {
711    /// Determines whether a [`Natural`] can be converted to an [`Float`], taking the [`Natural`] by
712    /// reference.
713    ///
714    /// The [`Natural`]s that are convertible to [`Float`]s are those whose that would not overflow:
715    /// that is, those that are less than $2^{2^{30}-1}$.
716    ///
717    /// # Worst-case complexity
718    /// $T(n) = O(n)$
719    ///
720    /// $M(n) = O(1)$
721    ///
722    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
723    ///
724    /// # Examples
725    /// ```
726    /// use malachite_base::num::basic::traits::Zero;
727    /// use malachite_base::num::conversion::traits::ConvertibleFrom;
728    /// use malachite_float::Float;
729    /// use malachite_nz::natural::Natural;
730    ///
731    /// assert_eq!(Float::convertible_from(&Natural::ZERO), true);
732    /// assert_eq!(Float::convertible_from(&Natural::from(3u8)), true);
733    /// ```
734    #[inline]
735    fn convertible_from(x: &Natural) -> bool {
736        *x == 0
737            || (Self::MIN_EXPONENT..=Self::MAX_EXPONENT)
738                .contains(&i32::saturating_from(x.floor_log_base_2()).saturating_add(1))
739    }
740}