malachite_float/float/basic/get_and_set.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::InnerFloat::Finite;
10use crate::{Float, significand_bits};
11use core::cmp::Ordering::{self, *};
12use malachite_base::num::arithmetic::traits::{
13 NegAssign, RoundToMultipleOfPowerOf2, RoundToMultipleOfPowerOf2Assign,
14};
15use malachite_base::num::basic::integers::PrimitiveInt;
16use malachite_base::num::basic::traits::{Infinity, NegativeInfinity};
17use malachite_base::num::conversion::traits::ExactFrom;
18use malachite_base::num::logic::traits::SignificantBits;
19use malachite_base::rounding_modes::RoundingMode::{self, *};
20use malachite_nz::natural::Natural;
21use malachite_nz::platform::Limb;
22
23const PREC_ROUND_THRESHOLD: u64 = 1500;
24
25impl Float {
26 /// Gets the significand of a [`Float`], taking the [`Float`] by value.
27 ///
28 /// The significand is the smallest positive integer which is some power of 2 times the
29 /// [`Float`], and whose number of significant bits is a multiple of the limb width. If the
30 /// [`Float`] is NaN, infinite, or zero, then `None` is returned.
31 ///
32 /// # Worst-case complexity
33 /// $T(n) = O(n)$
34 ///
35 /// $M(n) = O(n)$
36 ///
37 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
38 /// significand is cloned.
39 ///
40 /// # Examples
41 /// ```
42 /// #[cfg(not(feature = "32_bit_limbs"))]
43 /// use malachite_base::num::arithmetic::traits::PowerOf2;
44 /// #[cfg(not(feature = "32_bit_limbs"))]
45 /// use malachite_base::num::basic::traits::One;
46 /// use malachite_base::num::basic::traits::{Infinity, NaN, Zero};
47 /// use malachite_float::Float;
48 /// #[cfg(not(feature = "32_bit_limbs"))]
49 /// use malachite_nz::natural::Natural;
50 ///
51 /// assert_eq!(Float::NAN.to_significand(), None);
52 /// assert_eq!(Float::INFINITY.to_significand(), None);
53 /// assert_eq!(Float::ZERO.to_significand(), None);
54 ///
55 /// #[cfg(not(feature = "32_bit_limbs"))]
56 /// {
57 /// assert_eq!(Float::ONE.to_significand(), Some(Natural::power_of_2(63)));
58 /// assert_eq!(
59 /// Float::from(std::f64::consts::PI).to_significand().unwrap(),
60 /// 14488038916154245120u64
61 /// );
62 /// }
63 /// ```
64 #[inline]
65 pub fn to_significand(&self) -> Option<Natural> {
66 match self {
67 Self(Finite { significand, .. }) => Some(significand.clone()),
68 _ => None,
69 }
70 }
71
72 /// Gets the significand of a [`Float`], taking the [`Float`] by reference.
73 ///
74 /// The significand is the smallest positive integer which is some power of 2 times the
75 /// [`Float`], and whose number of significant bits is a multiple of the limb width. If the
76 /// [`Float`] is NaN, infinite, or zero, then `None` is returned.
77 ///
78 /// # Worst-case complexity
79 /// Constant time and additional memory.
80 ///
81 /// # Examples
82 /// ```
83 /// #[cfg(not(feature = "32_bit_limbs"))]
84 /// use malachite_base::num::arithmetic::traits::PowerOf2;
85 /// #[cfg(not(feature = "32_bit_limbs"))]
86 /// use malachite_base::num::basic::traits::One;
87 /// use malachite_base::num::basic::traits::{Infinity, NaN, Zero};
88 /// use malachite_float::Float;
89 /// #[cfg(not(feature = "32_bit_limbs"))]
90 /// use malachite_nz::natural::Natural;
91 ///
92 /// assert_eq!(Float::NAN.into_significand(), None);
93 /// assert_eq!(Float::INFINITY.into_significand(), None);
94 /// assert_eq!(Float::ZERO.into_significand(), None);
95 ///
96 /// #[cfg(not(feature = "32_bit_limbs"))]
97 /// {
98 /// assert_eq!(Float::ONE.into_significand(), Some(Natural::power_of_2(63)));
99 /// assert_eq!(
100 /// Float::from(std::f64::consts::PI)
101 /// .into_significand()
102 /// .unwrap(),
103 /// 14488038916154245120u64
104 /// );
105 /// }
106 /// ```
107 #[allow(clippy::missing_const_for_fn)] // destructor doesn't work with const
108 #[inline]
109 pub fn into_significand(self) -> Option<Natural> {
110 match self {
111 Self(Finite { significand, .. }) => Some(significand),
112 _ => None,
113 }
114 }
115
116 /// Returns a reference to the significand of a [`Float`].
117 ///
118 /// The significand is the smallest positive integer which is some power of 2 times the
119 /// [`Float`], and whose number of significant bits is a multiple of the limb width. If the
120 /// [`Float`] is NaN, infinite, or zero, then `None` is returned.
121 ///
122 /// # Worst-case complexity
123 /// Constant time and additional memory.
124 ///
125 /// # Examples
126 /// ```
127 /// #[cfg(not(feature = "32_bit_limbs"))]
128 /// use malachite_base::num::arithmetic::traits::PowerOf2;
129 /// #[cfg(not(feature = "32_bit_limbs"))]
130 /// use malachite_base::num::basic::traits::One;
131 /// use malachite_base::num::basic::traits::{Infinity, NaN, Zero};
132 /// use malachite_float::Float;
133 /// #[cfg(not(feature = "32_bit_limbs"))]
134 /// use malachite_nz::natural::Natural;
135 ///
136 /// assert_eq!(Float::NAN.significand_ref(), None);
137 /// assert_eq!(Float::INFINITY.significand_ref(), None);
138 /// assert_eq!(Float::ZERO.significand_ref(), None);
139 ///
140 /// #[cfg(not(feature = "32_bit_limbs"))]
141 /// {
142 /// assert_eq!(
143 /// *Float::ONE.significand_ref().unwrap(),
144 /// Natural::power_of_2(63)
145 /// );
146 /// assert_eq!(
147 /// *Float::from(std::f64::consts::PI).significand_ref().unwrap(),
148 /// 14488038916154245120u64
149 /// );
150 /// }
151 /// ```
152 #[inline]
153 pub const fn significand_ref(&self) -> Option<&Natural> {
154 match self {
155 Self(Finite { significand, .. }) => Some(significand),
156 _ => None,
157 }
158 }
159
160 /// Returns a [`Float`]'s exponent.
161 ///
162 /// $$
163 /// f(\text{NaN}) = f(\pm\infty) = f(\pm 0.0) = \text{None},
164 /// $$
165 ///
166 /// and, if $x$ is finite and nonzero,
167 ///
168 /// $$
169 /// f(x) = \operatorname{Some}(\lfloor \log_2 |x| \rfloor + 1).
170 /// $$
171 ///
172 /// The output is in the range $[-(2^{30}-1), 2^{30}-1]$.
173 ///
174 /// # Worst-case complexity
175 /// Constant time and additional memory.
176 ///
177 /// # Examples
178 /// ```
179 /// use malachite_base::num::arithmetic::traits::PowerOf2;
180 /// use malachite_base::num::basic::traits::{Infinity, NaN, One, Zero};
181 /// use malachite_float::Float;
182 ///
183 /// assert_eq!(Float::NAN.get_exponent(), None);
184 /// assert_eq!(Float::INFINITY.get_exponent(), None);
185 /// assert_eq!(Float::ZERO.get_exponent(), None);
186 ///
187 /// assert_eq!(Float::ONE.get_exponent(), Some(1));
188 /// assert_eq!(Float::from(std::f64::consts::PI).get_exponent(), Some(2));
189 /// assert_eq!(Float::power_of_2(100u64).get_exponent(), Some(101));
190 /// assert_eq!(Float::power_of_2(-100i64).get_exponent(), Some(-99));
191 /// ```
192 #[inline]
193 pub const fn get_exponent(&self) -> Option<i32> {
194 match self {
195 Self(Finite { exponent, .. }) => Some(*exponent),
196 _ => None,
197 }
198 }
199
200 /// Returns a [`Float`]'s precision. The precision is a positive integer denoting how many of
201 /// the [`Float`]'s bits are significant.
202 ///
203 /// Only [`Float`]s that are finite and nonzero have a precision. For other [`Float`]s, `None`
204 /// is returned.
205 ///
206 /// # Worst-case complexity
207 /// Constant time and additional memory.
208 ///
209 /// # Examples
210 /// ```
211 /// use malachite_base::num::basic::traits::{Infinity, NaN, One, Zero};
212 /// use malachite_float::Float;
213 ///
214 /// assert_eq!(Float::NAN.get_prec(), None);
215 /// assert_eq!(Float::INFINITY.get_prec(), None);
216 /// assert_eq!(Float::ZERO.get_prec(), None);
217 ///
218 /// assert_eq!(Float::ONE.get_prec(), Some(1));
219 /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
220 /// assert_eq!(Float::from(std::f64::consts::PI).get_prec(), Some(50));
221 /// ```
222 #[inline]
223 pub const fn get_prec(&self) -> Option<u64> {
224 match self {
225 Self(Finite { precision, .. }) => Some(*precision),
226 _ => None,
227 }
228 }
229
230 /// Returns the minimum precision necessary to represent the given [`Float`]'s value.
231 ///
232 /// For example, `Float:one_prec(100)` has a precision of 100, but its minimum precision is 1,
233 /// because that's all that's necessary to represent the value 1.
234 ///
235 /// The minimum precision is always less than or equal to the actual precision.
236 ///
237 /// Only [`Float`]s that are finite and nonzero have a minimum precision. For other [`Float`]s,
238 /// `None` is returned.
239 ///
240 /// # Worst-case complexity
241 /// $T(n) = O(n)$
242 ///
243 /// $M(n) = O(1)$
244 ///
245 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
246 /// trailing-zeros scan runs through the low zero limbs of the significand.
247 ///
248 /// # Examples
249 /// ```
250 /// use malachite_base::num::basic::traits::{Infinity, NaN, One, Zero};
251 /// use malachite_float::Float;
252 ///
253 /// assert_eq!(Float::NAN.get_min_prec(), None);
254 /// assert_eq!(Float::INFINITY.get_min_prec(), None);
255 /// assert_eq!(Float::ZERO.get_min_prec(), None);
256 ///
257 /// assert_eq!(Float::ONE.get_min_prec(), Some(1));
258 /// assert_eq!(Float::one_prec(100).get_min_prec(), Some(1));
259 /// assert_eq!(Float::from(std::f64::consts::PI).get_min_prec(), Some(50));
260 /// ```
261 pub fn get_min_prec(&self) -> Option<u64> {
262 match self {
263 Self(Finite { significand, .. }) => {
264 Some(significand_bits(significand) - significand.trailing_zeros().unwrap())
265 }
266 _ => None,
267 }
268 }
269
270 /// Changes a [`Float`]'s precision. If the precision decreases, rounding may be necessary, and
271 /// will use the provided [`RoundingMode`].
272 ///
273 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
274 /// equal to the original value.
275 ///
276 /// Unlike the similarly-named MPFR function `mpfr_set_prec`, which discards the value of its
277 /// argument, this function preserves the value, rounding it if necessary; it corresponds to
278 /// MPFR's `mpfr_prec_round`.
279 ///
280 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
281 /// overflow. This is even possible if `rm` is `Nearest`, even though infinity is never nearer
282 /// to the exact result than any finite [`Float`] is. This is to match the behavior of MPFR.
283 ///
284 /// This function never underflows.
285 ///
286 /// # Worst-case complexity
287 /// $T(n, m) = O(n + m)$
288 ///
289 /// $M(n) = O(n)$
290 ///
291 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
292 /// `self.significant_bits()`: when the precision shrinks, rounding must examine the bits that
293 /// are discarded.
294 ///
295 /// # Panics
296 /// Panics if `prec` is zero or if `rm` is [`Exact`] but setting the desired precision requires
297 /// rounding.
298 ///
299 /// # Examples
300 /// ```
301 /// use malachite_base::rounding_modes::RoundingMode::*;
302 /// use malachite_float::Float;
303 /// use std::cmp::Ordering::*;
304 ///
305 /// let original_x = Float::from(1.0f64 / 3.0);
306 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
307 /// assert_eq!(original_x.get_prec(), Some(53));
308 ///
309 /// let mut x = original_x.clone();
310 /// assert_eq!(x.set_prec_round(100, Exact), Equal);
311 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
312 /// assert_eq!(x.get_prec(), Some(100));
313 ///
314 /// let mut x = original_x.clone();
315 /// assert_eq!(x.set_prec_round(10, Floor), Less);
316 /// assert_eq!(x.to_string(), "0.33301");
317 /// assert_eq!(x.get_prec(), Some(10));
318 ///
319 /// let mut x = original_x.clone();
320 /// assert_eq!(x.set_prec_round(10, Ceiling), Greater);
321 /// assert_eq!(x.to_string(), "0.33350");
322 /// assert_eq!(x.get_prec(), Some(10));
323 /// ```
324 pub fn set_prec_round(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
325 assert_ne!(prec, 0);
326 match self {
327 Self(Finite {
328 sign,
329 exponent,
330 precision,
331 significand,
332 }) => {
333 let target_bits = prec
334 .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
335 .0;
336 let significant_bits = significand_bits(significand);
337 let o;
338 if target_bits > significant_bits {
339 *significand <<= target_bits - significant_bits;
340 o = Equal;
341 } else {
342 let limb_count = significand.limb_count();
343 let abs_rm = if *sign { rm } else { -rm };
344 o = significand
345 .round_to_multiple_of_power_of_2_assign(significant_bits - prec, abs_rm);
346 if significand.limb_count() > limb_count {
347 if *exponent == Self::MAX_EXPONENT {
348 return if *sign {
349 *self = Self::INFINITY;
350 Greater
351 } else {
352 *self = Self::NEGATIVE_INFINITY;
353 Less
354 };
355 }
356 *significand >>= 1u32;
357 *exponent += 1;
358 }
359 *significand >>= significant_bits - target_bits;
360 }
361 *precision = prec;
362 if *sign { o } else { o.reverse() }
363 }
364 _ => Equal,
365 }
366 }
367
368 /// Changes a [`Float`]'s precision. If the precision decreases, rounding may be necessary, and
369 /// [`Nearest`] will be used.
370 ///
371 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
372 /// equal to the original value.
373 ///
374 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
375 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
376 /// is. This is to match the behavior of MPFR.
377 ///
378 /// This function never underflows.
379 ///
380 /// Unlike the similarly-named MPFR function `mpfr_set_prec`, which discards the value of its
381 /// argument, this function preserves the value, rounding it if necessary; it corresponds to
382 /// MPFR's `mpfr_prec_round`.
383 ///
384 /// To use a different rounding mode, try [`Float::set_prec_round`].
385 ///
386 /// # Worst-case complexity
387 /// $T(n, m) = O(n + m)$
388 ///
389 /// $M(n) = O(n)$
390 ///
391 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
392 /// `self.significant_bits()`: when the precision shrinks, rounding must examine the bits that
393 /// are discarded.
394 ///
395 /// # Examples
396 /// ```
397 /// use malachite_float::Float;
398 /// use std::cmp::Ordering::*;
399 ///
400 /// let original_x = Float::from(1.0f64 / 3.0);
401 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
402 /// assert_eq!(original_x.get_prec(), Some(53));
403 ///
404 /// let mut x = original_x.clone();
405 /// assert_eq!(x.set_prec(100), Equal);
406 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
407 /// assert_eq!(x.get_prec(), Some(100));
408 ///
409 /// let mut x = original_x.clone();
410 /// assert_eq!(x.set_prec(10), Greater);
411 /// assert_eq!(x.to_string(), "0.33350");
412 /// assert_eq!(x.get_prec(), Some(10));
413 /// ```
414 #[inline]
415 pub fn set_prec(&mut self, p: u64) -> Ordering {
416 self.set_prec_round(p, Nearest)
417 }
418
419 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
420 /// precision decreases, rounding may be necessary, and will use the provided [`RoundingMode`].
421 /// The input [`Float`] is taken by value.
422 ///
423 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
424 /// equal to the original value.
425 ///
426 /// If the input [`Float`] has the maximum exponent, it is possible for this function to
427 /// overflow. This is even possible if `rm` is `Nearest`, even though infinity is never nearer
428 /// to the exact result than any finite [`Float`] is. This is to match the behavior of MPFR.
429 ///
430 /// This function never underflows.
431 ///
432 /// # Worst-case complexity
433 /// $T(n, m) = O(n + m)$
434 ///
435 /// $M(n) = O(n)$
436 ///
437 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
438 /// `x.significant_bits()`: when the precision shrinks, rounding must examine the bits that are
439 /// discarded.
440 ///
441 /// # Panics
442 /// Panics if `prec` is zero or if `rm` is [`Exact`] but setting the desired precision requires
443 /// rounding.
444 ///
445 /// # Examples
446 /// ```
447 /// use malachite_base::rounding_modes::RoundingMode::*;
448 /// use malachite_float::Float;
449 /// use std::cmp::Ordering::*;
450 ///
451 /// let original_x = Float::from(1.0f64 / 3.0);
452 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
453 /// assert_eq!(original_x.get_prec(), Some(53));
454 ///
455 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 100, Exact);
456 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
457 /// assert_eq!(x.get_prec(), Some(100));
458 /// assert_eq!(o, Equal);
459 ///
460 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 10, Floor);
461 /// assert_eq!(x.to_string(), "0.33301");
462 /// assert_eq!(x.get_prec(), Some(10));
463 /// assert_eq!(o, Less);
464 ///
465 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 10, Ceiling);
466 /// assert_eq!(x.to_string(), "0.33350");
467 /// assert_eq!(x.get_prec(), Some(10));
468 /// assert_eq!(o, Greater);
469 /// ```
470 #[inline]
471 pub fn from_float_prec_round(mut x: Self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
472 let o = x.set_prec_round(prec, rm);
473 (x, o)
474 }
475
476 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
477 /// precision decreases, rounding may be necessary, and will use the provided [`RoundingMode`].
478 /// The input [`Float`] is taken by reference.
479 ///
480 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
481 /// equal to the original value.
482 ///
483 /// If the input [`Float`] has the maximum exponent, it is possible for this function to
484 /// overflow. This is even possible if `rm` is `Nearest`, even though infinity is never nearer
485 /// to the exact result than any finite [`Float`] is. This is to match the behavior of MPFR.
486 ///
487 /// This function never underflows.
488 ///
489 /// # Worst-case complexity
490 /// $T(n, m) = O(n + m)$
491 ///
492 /// $M(n) = O(n)$
493 ///
494 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
495 /// `x.significant_bits()`: when the precision shrinks, rounding must examine the bits that are
496 /// discarded.
497 ///
498 /// # Panics
499 /// Panics if `prec` is zero or if `rm` is [`Exact`] but setting the desired precision requires
500 /// rounding.
501 ///
502 /// # Examples
503 /// ```
504 /// use malachite_base::rounding_modes::RoundingMode::*;
505 /// use malachite_float::Float;
506 /// use std::cmp::Ordering::*;
507 ///
508 /// let original_x = Float::from(1.0f64 / 3.0);
509 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
510 /// assert_eq!(original_x.get_prec(), Some(53));
511 ///
512 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 100, Exact);
513 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
514 /// assert_eq!(x.get_prec(), Some(100));
515 /// assert_eq!(o, Equal);
516 ///
517 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 10, Floor);
518 /// assert_eq!(x.to_string(), "0.33301");
519 /// assert_eq!(x.get_prec(), Some(10));
520 /// assert_eq!(o, Less);
521 ///
522 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 10, Ceiling);
523 /// assert_eq!(x.to_string(), "0.33350");
524 /// assert_eq!(x.get_prec(), Some(10));
525 /// assert_eq!(o, Greater);
526 /// ```
527 pub fn from_float_prec_round_ref(x: &Self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
528 if x.significant_bits() < PREC_ROUND_THRESHOLD {
529 let mut x = x.clone();
530 let o = x.set_prec_round(prec, rm);
531 return (x, o);
532 }
533 match x {
534 // The fast path places the significand at an exponent equal to its bit count and shifts
535 // afterwards, so that intermediate exponent (plus a possible rounding carry) must stay
536 // within the valid range; otherwise it would silently overflow to infinity. For the
537 // enormous precisions that fail that test, fall back to cloning, whose cost is
538 // proportional to an input that is already that large. (`set_prec_round` works in place
539 // and never puts the bit count in the exponent.)
540 Self(Finite {
541 sign,
542 exponent,
543 significand,
544 ..
545 }) if significand_bits(significand) < const { (Self::MAX_EXPONENT - 1) as u64 } => {
546 let (mut y, mut o) = Self::from_natural_prec_round_ref(
547 significand,
548 prec,
549 if *sign { rm } else { -rm },
550 );
551 if !sign {
552 y.neg_assign();
553 o = o.reverse();
554 }
555 (
556 y >> (i32::exact_from(significand_bits(significand)) - exponent),
557 o,
558 )
559 }
560 Self(Finite { .. }) => {
561 let mut x = x.clone();
562 let o = x.set_prec_round(prec, rm);
563 (x, o)
564 }
565 _ => (x.clone(), Equal),
566 }
567 }
568
569 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
570 /// precision decreases, rounding may be necessary, and will use [`Nearest`]. The input
571 /// [`Float`] is taken by value.
572 ///
573 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
574 /// equal to the original value.
575 ///
576 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
577 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
578 /// is. This is to match the behavior of MPFR.
579 ///
580 /// This function never underflows.
581 ///
582 /// To use a different rounding mode, try [`Float::from_float_prec_round`].
583 ///
584 /// # Worst-case complexity
585 /// $T(n, m) = O(n + m)$
586 ///
587 /// $M(n) = O(n)$
588 ///
589 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
590 /// `x.significant_bits()`: when the precision shrinks, rounding must examine the bits that are
591 /// discarded.
592 ///
593 /// # Panics
594 /// Panics if `prec` is zero.
595 ///
596 /// # Examples
597 /// ```
598 /// use malachite_float::Float;
599 /// use std::cmp::Ordering::*;
600 ///
601 /// let original_x = Float::from(1.0f64 / 3.0);
602 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
603 /// assert_eq!(original_x.get_prec(), Some(53));
604 ///
605 /// let (x, o) = Float::from_float_prec(original_x.clone(), 100);
606 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
607 /// assert_eq!(x.get_prec(), Some(100));
608 /// assert_eq!(o, Equal);
609 ///
610 /// let (x, o) = Float::from_float_prec(original_x.clone(), 10);
611 /// assert_eq!(x.to_string(), "0.33350");
612 /// assert_eq!(x.get_prec(), Some(10));
613 /// assert_eq!(o, Greater);
614 /// ```
615 #[inline]
616 pub fn from_float_prec(mut x: Self, prec: u64) -> (Self, Ordering) {
617 let o = x.set_prec(prec);
618 (x, o)
619 }
620
621 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
622 /// precision decreases, rounding may be necessary, and will use [`Nearest`]. The input
623 /// [`Float`] is taken by reference.
624 ///
625 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
626 /// equal to the original value.
627 ///
628 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
629 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
630 /// is. This is to match the behavior of MPFR.
631 ///
632 /// This function never underflows.
633 ///
634 /// To use a different rounding mode, try [`Float::from_float_prec_round_ref`].
635 ///
636 /// # Worst-case complexity
637 /// $T(n, m) = O(n + m)$
638 ///
639 /// $M(n) = O(n)$
640 ///
641 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
642 /// `x.significant_bits()`: when the precision shrinks, rounding must examine the bits that are
643 /// discarded.
644 ///
645 /// # Panics
646 /// Panics if `prec` is zero.
647 ///
648 /// # Examples
649 /// ```
650 /// use malachite_float::Float;
651 /// use std::cmp::Ordering::*;
652 ///
653 /// let original_x = Float::from(1.0f64 / 3.0);
654 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
655 /// assert_eq!(original_x.get_prec(), Some(53));
656 ///
657 /// let (x, o) = Float::from_float_prec_ref(&original_x, 100);
658 /// assert_eq!(x.to_string(), "0.33333333333333331482961625624739");
659 /// assert_eq!(x.get_prec(), Some(100));
660 /// assert_eq!(o, Equal);
661 ///
662 /// let (x, o) = Float::from_float_prec_ref(&original_x, 10);
663 /// assert_eq!(x.to_string(), "0.33350");
664 /// assert_eq!(x.get_prec(), Some(10));
665 /// assert_eq!(o, Greater);
666 /// ```
667 #[inline]
668 pub fn from_float_prec_ref(x: &Self, prec: u64) -> (Self, Ordering) {
669 Self::from_float_prec_round_ref(x, prec, Nearest)
670 }
671}