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