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