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}