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::{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 /// 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 { o } else { o.reverse() }
347 }
348 _ => Equal,
349 }
350 }
351
352 /// Changes a [`Float`]'s precision. If the precision decreases, rounding may be necessary, and
353 /// [`Nearest`] will be used.
354 ///
355 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
356 /// equal to the original value.
357 ///
358 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
359 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
360 /// is. This is to match the behavior of MPFR.
361 ///
362 /// This function never underflows.
363 ///
364 /// To use a different rounding mode, try [`Float::set_prec_round`].
365 ///
366 /// # Worst-case complexity
367 /// $T(n) = O(n)$
368 ///
369 /// $M(n) = O(n)$
370 ///
371 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
372 ///
373 /// # Examples
374 /// ```
375 /// use malachite_float::Float;
376 /// use std::cmp::Ordering::*;
377 ///
378 /// let original_x = Float::from(1.0f64 / 3.0);
379 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
380 /// assert_eq!(original_x.get_prec(), Some(53));
381 ///
382 /// let mut x = original_x.clone();
383 /// assert_eq!(x.set_prec(100), Equal);
384 /// assert_eq!(x.to_string(), "0.3333333333333333148296162562474");
385 /// assert_eq!(x.get_prec(), Some(100));
386 ///
387 /// let mut x = original_x.clone();
388 /// assert_eq!(x.set_prec(10), Greater);
389 /// assert_eq!(x.to_string(), "0.3335");
390 /// assert_eq!(x.get_prec(), Some(10));
391 /// ```
392 #[inline]
393 pub fn set_prec(&mut self, p: u64) -> Ordering {
394 self.set_prec_round(p, Nearest)
395 }
396
397 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
398 /// precision decreases, rounding may be necessary, and will use the provided [`RoundingMode`].
399 /// The input [`Float`] is taken by value.
400 ///
401 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
402 /// equal to the original value.
403 ///
404 /// If the input [`Float`] has the maximum exponent, it is possible for this function to
405 /// overflow. This is even possible if `rm` is `Nearest`, even though infinity is never nearer
406 /// to the exact result than any finite [`Float`] is. This is to match the behavior of MPFR.
407 ///
408 /// This function never underflows.
409 ///
410 /// # Worst-case complexity
411 /// $T(n) = O(n)$
412 ///
413 /// $M(n) = O(n)$
414 ///
415 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
416 ///
417 /// # Panics
418 /// Panics if `prec` is zero or if `rm` is [`Exact`] but setting the desired precision requires
419 /// rounding.
420 ///
421 /// # Examples
422 /// ```
423 /// use malachite_base::rounding_modes::RoundingMode::*;
424 /// use malachite_float::Float;
425 /// use std::cmp::Ordering::*;
426 ///
427 /// let original_x = Float::from(1.0f64 / 3.0);
428 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
429 /// assert_eq!(original_x.get_prec(), Some(53));
430 ///
431 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 100, Exact);
432 /// assert_eq!(x.to_string(), "0.3333333333333333148296162562474");
433 /// assert_eq!(x.get_prec(), Some(100));
434 /// assert_eq!(o, Equal);
435 ///
436 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 10, Floor);
437 /// assert_eq!(x.to_string(), "0.333");
438 /// assert_eq!(x.get_prec(), Some(10));
439 /// assert_eq!(o, Less);
440 ///
441 /// let (x, o) = Float::from_float_prec_round(original_x.clone(), 10, Ceiling);
442 /// assert_eq!(x.to_string(), "0.3335");
443 /// assert_eq!(x.get_prec(), Some(10));
444 /// assert_eq!(o, Greater);
445 /// ```
446 #[inline]
447 pub fn from_float_prec_round(mut x: Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
448 let o = x.set_prec_round(prec, rm);
449 (x, o)
450 }
451
452 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
453 /// precision decreases, rounding may be necessary, and will use the provided [`RoundingMode`].
454 /// The input [`Float`] is taken by reference.
455 ///
456 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
457 /// equal to the original value.
458 ///
459 /// If the input [`Float`] has the maximum exponent, it is possible for this function to
460 /// overflow. This is even possible if `rm` is `Nearest`, even though infinity is never nearer
461 /// to the exact result than any finite [`Float`] is. This is to match the behavior of MPFR.
462 ///
463 /// This function never underflows.
464 ///
465 /// # Worst-case complexity
466 /// $T(n) = O(n)$
467 ///
468 /// $M(n) = O(n)$
469 ///
470 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
471 ///
472 /// # Panics
473 /// Panics if `prec` is zero or if `rm` is [`Exact`] but setting the desired precision requires
474 /// rounding.
475 ///
476 /// # Examples
477 /// ```
478 /// use malachite_base::rounding_modes::RoundingMode::*;
479 /// use malachite_float::Float;
480 /// use std::cmp::Ordering::*;
481 ///
482 /// let original_x = Float::from(1.0f64 / 3.0);
483 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
484 /// assert_eq!(original_x.get_prec(), Some(53));
485 ///
486 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 100, Exact);
487 /// assert_eq!(x.to_string(), "0.3333333333333333148296162562474");
488 /// assert_eq!(x.get_prec(), Some(100));
489 /// assert_eq!(o, Equal);
490 ///
491 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 10, Floor);
492 /// assert_eq!(x.to_string(), "0.333");
493 /// assert_eq!(x.get_prec(), Some(10));
494 /// assert_eq!(o, Less);
495 ///
496 /// let (x, o) = Float::from_float_prec_round_ref(&original_x, 10, Ceiling);
497 /// assert_eq!(x.to_string(), "0.3335");
498 /// assert_eq!(x.get_prec(), Some(10));
499 /// assert_eq!(o, Greater);
500 /// ```
501 pub fn from_float_prec_round_ref(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
502 if x.significant_bits() < PREC_ROUND_THRESHOLD {
503 let mut x = x.clone();
504 let o = x.set_prec_round(prec, rm);
505 return (x, o);
506 }
507 match x {
508 Float(Finite {
509 sign,
510 exponent,
511 significand,
512 ..
513 }) => {
514 let (mut y, mut o) = Float::from_natural_prec_round_ref(
515 significand,
516 prec,
517 if *sign { rm } else { -rm },
518 );
519 if !sign {
520 y.neg_assign();
521 o = o.reverse();
522 }
523 (
524 y >> (i32::exact_from(significand_bits(significand)) - exponent),
525 o,
526 )
527 }
528 _ => (x.clone(), Equal),
529 }
530 }
531
532 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
533 /// precision decreases, rounding may be necessary, and will use [`Nearest`]. The input
534 /// [`Float`] is taken by value.
535 ///
536 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
537 /// equal to the original value.
538 ///
539 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
540 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
541 /// is. This is to match the behavior of MPFR.
542 ///
543 /// This function never underflows.
544 ///
545 /// To use a different rounding mode, try [`Float::from_float_prec_round`].
546 ///
547 /// # Worst-case complexity
548 /// $T(n) = O(n)$
549 ///
550 /// $M(n) = O(n)$
551 ///
552 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
553 ///
554 /// # Panics
555 /// Panics if `prec` is zero.
556 ///
557 /// # Examples
558 /// ```
559 /// use malachite_float::Float;
560 /// use std::cmp::Ordering::*;
561 ///
562 /// let original_x = Float::from(1.0f64 / 3.0);
563 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
564 /// assert_eq!(original_x.get_prec(), Some(53));
565 ///
566 /// let (x, o) = Float::from_float_prec(original_x.clone(), 100);
567 /// assert_eq!(x.to_string(), "0.3333333333333333148296162562474");
568 /// assert_eq!(x.get_prec(), Some(100));
569 /// assert_eq!(o, Equal);
570 ///
571 /// let (x, o) = Float::from_float_prec(original_x.clone(), 10);
572 /// assert_eq!(x.to_string(), "0.3335");
573 /// assert_eq!(x.get_prec(), Some(10));
574 /// assert_eq!(o, Greater);
575 /// ```
576 #[inline]
577 pub fn from_float_prec(mut x: Float, prec: u64) -> (Float, Ordering) {
578 let o = x.set_prec(prec);
579 (x, o)
580 }
581
582 /// Creates a [`Float`] from another [`Float`], possibly with a different precision. If the
583 /// precision decreases, rounding may be necessary, and will use [`Nearest`]. The input
584 /// [`Float`] is taken by reference.
585 ///
586 /// Returns an [`Ordering`], indicating whether the final value is less than, greater than, or
587 /// equal to the original value.
588 ///
589 /// If the [`Float`] originally had the maximum exponent, it is possible for this function to
590 /// overflow, even though infinity is never nearer to the exact result than any finite [`Float`]
591 /// is. This is to match the behavior of MPFR.
592 ///
593 /// This function never underflows.
594 ///
595 /// To use a different rounding mode, try [`Float::from_float_prec_round_ref`].
596 ///
597 /// # Worst-case complexity
598 /// $T(n) = O(n)$
599 ///
600 /// $M(n) = O(n)$
601 ///
602 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
603 ///
604 /// # Panics
605 /// Panics if `prec` is zero.
606 ///
607 /// # Examples
608 /// ```
609 /// use malachite_float::Float;
610 /// use std::cmp::Ordering::*;
611 ///
612 /// let original_x = Float::from(1.0f64 / 3.0);
613 /// assert_eq!(original_x.to_string(), "0.33333333333333331");
614 /// assert_eq!(original_x.get_prec(), Some(53));
615 ///
616 /// let (x, o) = Float::from_float_prec_ref(&original_x, 100);
617 /// assert_eq!(x.to_string(), "0.3333333333333333148296162562474");
618 /// assert_eq!(x.get_prec(), Some(100));
619 /// assert_eq!(o, Equal);
620 ///
621 /// let (x, o) = Float::from_float_prec_ref(&original_x, 10);
622 /// assert_eq!(x.to_string(), "0.3335");
623 /// assert_eq!(x.get_prec(), Some(10));
624 /// assert_eq!(o, Greater);
625 /// ```
626 #[inline]
627 pub fn from_float_prec_ref(x: &Float, prec: u64) -> (Float, Ordering) {
628 Float::from_float_prec_round_ref(x, prec, Nearest)
629 }
630}