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 if let Ok(bits_i32) = i32::try_from(bits)
392 && bits_i32 <= Self::MAX_EXPONENT
393 {
394 let mut f = Self(Finite {
395 sign: true,
396 exponent: bits_i32,
397 precision: bits,
398 significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
399 });
400 let o = f.set_prec_round(prec, rm);
401 return (f, o);
402 }
403 match rm {
404 Up | Ceiling | Nearest => (Self::INFINITY, Greater),
405 Floor | Down => (Self::max_finite_value_with_prec(prec), Less),
406 Exact => panic!("Inexact conversion from Natural to Float"),
407 }
408 }
409
410 /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference. If the [`Float`]
411 /// is nonzero, it has the specified precision. If rounding is needed, the specified rounding
412 /// mode is used. An [`Ordering`] is also returned, indicating whether the returned value is
413 /// less than, equal to, or greater than the original value.
414 ///
415 /// If you're only using [`Nearest`], try using [`Float::from_natural_prec_ref`] instead.
416 ///
417 /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
418 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
419 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
420 ///
421 /// # Worst-case complexity
422 /// $T(m,n) = O(\max(m,n))$
423 ///
424 /// $M(n) = O(n)$
425 ///
426 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
427 /// `prec`.
428 ///
429 /// # Panics
430 /// Panics if `prec` is zero, or if `rm` is exact and the `Natural` cannot be exactly
431 /// represented with the specified precision.
432 ///
433 /// # Examples
434 /// ```
435 /// use malachite_base::num::basic::traits::Zero;
436 /// use malachite_base::rounding_modes::RoundingMode::*;
437 /// use malachite_float::Float;
438 /// use malachite_nz::natural::Natural;
439 /// use std::cmp::Ordering::*;
440 ///
441 /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::ZERO, 10, Exact);
442 /// assert_eq!(x.to_string(), "0.0");
443 /// assert_eq!(o, Equal);
444 ///
445 /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 20, Exact);
446 /// assert_eq!(x.to_string(), "123.0");
447 /// assert_eq!(x.get_prec(), Some(20));
448 /// assert_eq!(o, Equal);
449 ///
450 /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 4, Floor);
451 /// assert_eq!(x.to_string(), "1.2e2");
452 /// assert_eq!(x.get_prec(), Some(4));
453 /// assert_eq!(o, Less);
454 ///
455 /// let (x, o) = Float::from_natural_prec_round_ref(&Natural::from(123u32), 4, Ceiling);
456 /// assert_eq!(x.to_string(), "1.3e2");
457 /// assert_eq!(x.get_prec(), Some(4));
458 /// assert_eq!(o, Greater);
459 /// ```
460 #[inline]
461 pub fn from_natural_prec_round_ref(
462 x: &Natural,
463 prec: u64,
464 rm: RoundingMode,
465 ) -> (Self, Ordering) {
466 assert_ne!(prec, 0);
467 if *x == 0u32 {
468 return (Self::ZERO, Equal);
469 }
470 let bits = x.significant_bits();
471 if bits <= prec {
472 if let Ok(bits_i32) = i32::try_from(bits)
473 && bits_i32 <= Self::MAX_EXPONENT
474 {
475 let mut f = Self(Finite {
476 sign: true,
477 exponent: bits_i32,
478 precision: bits,
479 significand: x << bits.neg_mod_power_of_2(Limb::LOG_WIDTH),
480 });
481 let o = f.set_prec_round(prec, rm);
482 return (f, o);
483 }
484 match rm {
485 Up | Ceiling | Nearest => (Self::INFINITY, Greater),
486 Floor | Down => (Self::max_finite_value_with_prec(prec), Less),
487 Exact => panic!("Inexact conversion from Natural to Float"),
488 }
489 } else {
490 from_natural_prec_round_helper(x, prec, rm, bits)
491 }
492 }
493
494 /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by value. If the [`Float`] is
495 /// nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
496 /// whether the returned value is less than, equal to, or greater than the original value.
497 ///
498 /// If you want the [`Float`]'s precision to be equal to the [`Natural`]'s number of significant
499 /// bits, try just using `Float::try_from` instead.
500 ///
501 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
502 /// as well as a precision, try [`Float::from_natural_prec_round`].
503 ///
504 /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
505 /// function overflows to $\infty$.
506 ///
507 /// # Worst-case complexity
508 /// $T(m,n) = O(\max(m,n))$
509 ///
510 /// $M(n) = O(n)$
511 ///
512 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
513 /// `prec`.
514 ///
515 /// # Panics
516 /// Panics if `prec` is zero.
517 ///
518 /// # Examples
519 /// ```
520 /// use malachite_base::num::basic::traits::Zero;
521 /// use malachite_float::Float;
522 /// use malachite_nz::natural::Natural;
523 /// use std::cmp::Ordering::*;
524 ///
525 /// let (x, o) = Float::from_natural_prec(Natural::ZERO, 10);
526 /// assert_eq!(x.to_string(), "0.0");
527 /// assert_eq!(o, Equal);
528 ///
529 /// let (x, o) = Float::from_natural_prec(Natural::from(123u32), 20);
530 /// assert_eq!(x.to_string(), "123.0");
531 /// assert_eq!(x.get_prec(), Some(20));
532 /// assert_eq!(o, Equal);
533 ///
534 /// let (x, o) = Float::from_natural_prec(Natural::from(123u32), 4);
535 /// assert_eq!(x.to_string(), "1.2e2");
536 /// assert_eq!(x.get_prec(), Some(4));
537 /// assert_eq!(o, Less);
538 /// ```
539 #[inline]
540 pub fn from_natural_prec(x: Natural, prec: u64) -> (Self, Ordering) {
541 Self::from_natural_prec_round(x, prec, Nearest)
542 }
543
544 /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference. If the [`Float`]
545 /// is nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
546 /// whether the returned value is less than, equal to, or greater than the original value.
547 ///
548 /// If you want the [`Float`]'s precision to be equal to the [`Natural`]'s number of significant
549 /// bits, try just using `Float::try_from` instead.
550 ///
551 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
552 /// as well as a precision, try [`Float::from_natural_prec_round_ref`].
553 ///
554 /// - If the [`Natural`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
555 /// function overflows to $\infty$.
556 ///
557 /// # Worst-case complexity
558 /// $T(m,n) = O(\max(m,n))$
559 ///
560 /// $M(n) = O(n)$
561 ///
562 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
563 /// `prec`.
564 ///
565 /// # Panics
566 /// Panics if `prec` is zero.
567 ///
568 /// # Examples
569 /// ```
570 /// use malachite_base::num::basic::traits::Zero;
571 /// use malachite_float::Float;
572 /// use malachite_nz::natural::Natural;
573 /// use std::cmp::Ordering::*;
574 ///
575 /// let (x, o) = Float::from_natural_prec_ref(&Natural::ZERO, 10);
576 /// assert_eq!(x.to_string(), "0.0");
577 /// assert_eq!(o, Equal);
578 ///
579 /// let (x, o) = Float::from_natural_prec_ref(&Natural::from(123u32), 20);
580 /// assert_eq!(x.to_string(), "123.0");
581 /// assert_eq!(x.get_prec(), Some(20));
582 /// assert_eq!(o, Equal);
583 ///
584 /// let (x, o) = Float::from_natural_prec_ref(&Natural::from(123u32), 4);
585 /// assert_eq!(x.to_string(), "1.2e2");
586 /// assert_eq!(x.get_prec(), Some(4));
587 /// assert_eq!(o, Less);
588 /// ```
589 #[inline]
590 pub fn from_natural_prec_ref(x: &Natural, prec: u64) -> (Self, Ordering) {
591 Self::from_natural_prec_round_ref(x, prec, Nearest)
592 }
593}
594
595impl TryFrom<Natural> for Float {
596 type Error = FloatConversionError;
597
598 /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by value.
599 ///
600 /// If the [`Natural`] is nonzero, the precision of the [`Float`] is the minimum possible
601 /// precision to represent the [`Natural`] exactly. If you want to specify some other precision,
602 /// try [`Float::from_natural_prec`]. This may require rounding, which uses [`Nearest`] by
603 /// default. To specify a rounding mode as well as a precision, try
604 /// [`Float::from_natural_prec_round`].
605 ///
606 /// If the [`Natural`] is greater than or equal to $2^{2^{30}-1}$, this function returns an
607 /// overflow error.
608 ///
609 /// # Worst-case complexity
610 /// $T(n) = O(n)$
611 ///
612 /// $M(n) = O(1)$
613 ///
614 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
615 ///
616 /// # Examples
617 /// ```
618 /// use malachite_base::num::basic::traits::Zero;
619 /// use malachite_float::Float;
620 /// use malachite_nz::natural::Natural;
621 ///
622 /// assert_eq!(Float::try_from(Natural::ZERO).unwrap().to_string(), "0.0");
623 /// assert_eq!(
624 /// Float::try_from(Natural::from(123u32)).unwrap().to_string(),
625 /// "123.0"
626 /// );
627 /// assert_eq!(
628 /// Float::try_from(Natural::from(123u32)).unwrap().get_prec(),
629 /// Some(7)
630 /// );
631 /// assert_eq!(
632 /// Float::try_from(Natural::from(10u32)).unwrap().to_string(),
633 /// "10.0"
634 /// );
635 /// assert_eq!(
636 /// Float::try_from(Natural::from(10u32)).unwrap().get_prec(),
637 /// Some(3)
638 /// );
639 /// ```
640 fn try_from(x: Natural) -> Result<Self, Self::Error> {
641 if x == 0 {
642 Ok(Self::ZERO)
643 } else {
644 let bits = x.significant_bits();
645 let prec = bits - x.trailing_zeros().unwrap();
646 let (f, o) = Self::from_natural_prec_round(x, prec, Floor);
647 if o == Equal {
648 Ok(f)
649 } else {
650 Err(FloatConversionError::Overflow)
651 }
652 }
653 }
654}
655
656impl TryFrom<&Natural> for Float {
657 type Error = FloatConversionError;
658
659 /// Converts a [`Natural`] to a [`Float`], taking the [`Natural`] by reference.
660 ///
661 /// If the [`Natural`] is nonzero, the precision of the [`Float`] is the minimum possible
662 /// precision to represent the [`Natural`] exactly. If you want to specify some other precision,
663 /// try [`Float::from_natural_prec`]. This may require rounding, which uses [`Nearest`] by
664 /// default. To specify a rounding mode as well as a precision, try
665 /// [`Float::from_natural_prec_round`].
666 ///
667 /// If the [`Natural`] is greater than or equal to $2^{2^{30}-1}$, this function returns an
668 /// overflow error.
669 ///
670 /// # Worst-case complexity
671 /// $T(n) = O(n)$
672 ///
673 /// $M(n) = O(n)$
674 ///
675 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
676 ///
677 /// # Examples
678 /// ```
679 /// use malachite_base::num::basic::traits::Zero;
680 /// use malachite_float::Float;
681 /// use malachite_nz::natural::Natural;
682 ///
683 /// assert_eq!(Float::try_from(&Natural::ZERO).unwrap().to_string(), "0.0");
684 /// assert_eq!(
685 /// Float::try_from(&Natural::from(123u32)).unwrap().to_string(),
686 /// "123.0"
687 /// );
688 /// assert_eq!(
689 /// Float::try_from(&Natural::from(123u32)).unwrap().get_prec(),
690 /// Some(7)
691 /// );
692 /// assert_eq!(
693 /// Float::try_from(&Natural::from(10u32)).unwrap().to_string(),
694 /// "10.0"
695 /// );
696 /// assert_eq!(
697 /// Float::try_from(&Natural::from(10u32)).unwrap().get_prec(),
698 /// Some(3)
699 /// );
700 /// ```
701 #[inline]
702 fn try_from(x: &Natural) -> Result<Self, Self::Error> {
703 if *x == 0 {
704 Ok(Self::ZERO)
705 } else {
706 let bits = x.significant_bits();
707 let prec = bits - x.trailing_zeros().unwrap();
708 let (f, o) = Self::from_natural_prec_round_ref(x, prec, Floor);
709 if o == Equal {
710 Ok(f)
711 } else {
712 Err(FloatConversionError::Overflow)
713 }
714 }
715 }
716}
717
718impl ConvertibleFrom<&Natural> for Float {
719 /// Determines whether a [`Natural`] can be converted to an [`Float`], taking the [`Natural`] by
720 /// reference.
721 ///
722 /// The [`Natural`]s that are convertible to [`Float`]s are those whose that would not overflow:
723 /// that is, those that are less than $2^{2^{30}-1}$.
724 ///
725 /// # Worst-case complexity
726 /// $T(n) = O(n)$
727 ///
728 /// $M(n) = O(1)$
729 ///
730 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
731 ///
732 /// # Examples
733 /// ```
734 /// use malachite_base::num::basic::traits::Zero;
735 /// use malachite_base::num::conversion::traits::ConvertibleFrom;
736 /// use malachite_float::Float;
737 /// use malachite_nz::natural::Natural;
738 ///
739 /// assert_eq!(Float::convertible_from(&Natural::ZERO), true);
740 /// assert_eq!(Float::convertible_from(&Natural::from(3u8)), true);
741 /// ```
742 #[inline]
743 fn convertible_from(x: &Natural) -> bool {
744 *x == 0
745 || (Self::MIN_EXPONENT..=Self::MAX_EXPONENT)
746 .contains(&i32::saturating_from(x.floor_log_base_2()).saturating_add(1))
747 }
748}