malachite_float/conversion/from_rational.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::conversion::from_integer::{
11 from_integer_prec_round_zero_exponent, from_integer_zero_exponent,
12};
13use crate::conversion::from_natural::{
14 from_natural_prec_round_zero_exponent, from_natural_prec_round_zero_exponent_ref,
15 from_natural_zero_exponent, from_natural_zero_exponent_ref,
16};
17use crate::{Float, significand_bits};
18use core::cmp::Ordering::{self, *};
19use core::cmp::max;
20use malachite_base::num::arithmetic::traits::{
21 CheckedLogBase2, IsPowerOf2, NegAssign, NegModPowerOf2, RoundToMultipleOfPowerOf2, UnsignedAbs,
22};
23use malachite_base::num::basic::integers::PrimitiveInt;
24use malachite_base::num::basic::traits::{Infinity, NegativeInfinity, NegativeZero, Zero};
25use malachite_base::num::conversion::traits::{
26 ConvertibleFrom, ExactFrom, RoundingFrom, SaturatingFrom,
27};
28use malachite_base::num::logic::traits::SignificantBits;
29use malachite_base::rounding_modes::RoundingMode::{self, *};
30use malachite_nz::integer::Integer;
31use malachite_nz::platform::Limb;
32use malachite_q::Rational;
33use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
34
35pub_test! {from_rational_prec_round_direct(
36 x: Rational,
37 prec: u64,
38 rm: RoundingMode,
39) -> (Float, Ordering) {
40 assert_ne!(prec, 0);
41 let sign = x >= 0;
42 if let Some(pow) = x.denominator_ref().checked_log_base_2() {
43 let n = x.into_numerator();
44 let n_bits = n.significant_bits();
45 let (mut y, mut o) =
46 from_integer_prec_round_zero_exponent(Integer::from_sign_and_abs(sign, n), prec, rm);
47 o = y.shr_prec_round_assign_helper(i128::from(pow) - i128::from(n_bits), prec, rm, o);
48 assert!(rm != Exact || o == Equal, "Inexact conversion from Rational to Float");
49 (y, o)
50 } else {
51 let mut exponent = i32::saturating_from(x.floor_log_base_2_abs());
52 if exponent >= Float::MAX_EXPONENT {
53 return match (sign, rm) {
54 (true, Up | Ceiling | Nearest) => (Float::INFINITY, Greater),
55 (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
56 (false, Up | Floor | Nearest) => (Float::NEGATIVE_INFINITY, Less),
57 (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
58 (_, Exact) => panic!("Inexact conversion from Rational to Float"),
59 };
60 }
61 let (significand, o) =
62 Integer::rounding_from(x << (i128::exact_from(prec) - i128::from(exponent) - 1), rm);
63 let sign = significand >= 0;
64 let mut significand = significand.unsigned_abs();
65 let away_from_0 = if sign { Greater } else { Less };
66 if o == away_from_0 && significand.is_power_of_2() {
67 exponent += 1;
68 if exponent >= Float::MAX_EXPONENT {
69 return if sign {
70 (Float::INFINITY, Greater)
71 } else {
72 (Float::NEGATIVE_INFINITY, Less)
73 };
74 }
75 }
76 exponent += 1;
77 if exponent < Float::MIN_EXPONENT {
78 assert!(rm != Exact, "Inexact conversion from Rational to Float");
79 return if rm == Nearest
80 && exponent == Float::MIN_EXPONENT - 1
81 && (o == away_from_0.reverse() || !significand.is_power_of_2())
82 {
83 if sign {
84 (Float::min_positive_value_prec(prec), Greater)
85 } else {
86 (-Float::min_positive_value_prec(prec), Less)
87 }
88 } else {
89 match (sign, rm) {
90 (true, Up | Ceiling) => (Float::min_positive_value_prec(prec), Greater),
91 (true, Floor | Down | Nearest) => (Float::ZERO, Less),
92 (false, Up | Floor) => (-Float::min_positive_value_prec(prec), Less),
93 (false, Ceiling | Down | Nearest) => (Float::NEGATIVE_ZERO, Greater),
94 (_, Exact) => unreachable!(),
95 }
96 };
97 }
98 significand <<= significand
99 .significant_bits()
100 .neg_mod_power_of_2(Limb::LOG_WIDTH);
101 let target_bits = prec
102 .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
103 .0;
104 let current_bits = significand_bits(&significand);
105 if current_bits > target_bits {
106 significand >>= current_bits - target_bits;
107 }
108 (
109 Float(Finite {
110 sign,
111 exponent,
112 precision: prec,
113 significand,
114 }),
115 o,
116 )
117 }
118}}
119
120pub_test! {from_rational_prec_round_using_div(
121 x: Rational,
122 prec: u64,
123 mut rm: RoundingMode,
124) -> (Float, Ordering) {
125 let sign = x >= 0;
126 if !sign {
127 rm.neg_assign();
128 }
129 let (n, d) = x.into_numerator_and_denominator();
130 let is_zero = n == 0;
131 let (f, o) = match (
132 if is_zero {
133 None
134 } else {
135 n.checked_log_base_2()
136 },
137 d.checked_log_base_2(),
138 ) {
139 (Some(log_n), Some(log_d)) => Float::power_of_2_prec_round(
140 i64::saturating_from(i128::from(log_n) - i128::from(log_d)),
141 prec,
142 rm,
143 ),
144 (None, Some(log_d)) => {
145 let bits = n.significant_bits();
146 let (mut f, mut o) = from_natural_prec_round_zero_exponent(n, prec, rm);
147 o = f.shr_prec_round_assign_helper(
148 i128::from(log_d) - i128::from(bits),
149 prec,
150 rm,
151 o,
152 );
153 (f, o)
154 }
155 (Some(log_n), None) => {
156 let bits = d.significant_bits();
157 let (mut f, mut o) =
158 from_natural_zero_exponent(d).reciprocal_prec_round(prec, rm);
159 o = f.shl_prec_round_assign_helper(
160 i128::from(log_n) - i128::from(bits),
161 prec,
162 rm,
163 o,
164 );
165 (f, o)
166 }
167 (None, None) => {
168 let n_bits = n.significant_bits();
169 let d_bits = d.significant_bits();
170 let (mut f, mut o) = from_natural_zero_exponent(n).div_prec_round(
171 from_natural_zero_exponent(d),
172 prec,
173 rm,
174 );
175 o = f.shl_prec_round_assign_helper(
176 i128::from(n_bits) - i128::from(d_bits),
177 prec,
178 rm,
179 o,
180 );
181 (f, o)
182 }
183 };
184 if sign {
185 (f, o)
186 } else {
187 (-f, o.reverse())
188 }
189}}
190
191pub_test! {from_rational_prec_round_ref_direct(
192 x: &Rational,
193 prec: u64,
194 rm: RoundingMode,
195) -> (Float, Ordering) {
196 assert_ne!(prec, 0);
197 let sign = *x >= 0;
198 if let Some(pow) = x.denominator_ref().checked_log_base_2() {
199 let n = x.numerator_ref();
200 let n_bits = n.significant_bits();
201 let (mut y, mut o) =
202 from_natural_prec_round_zero_exponent_ref(n, prec, if sign { rm } else { -rm });
203 o = y.shr_prec_round_assign_helper(
204 i128::from(pow) - i128::from(n_bits),
205 prec,
206 if sign { rm } else { -rm },
207 o,
208 );
209 assert!(rm != Exact || o == Equal, "Inexact conversion from Rational to Float");
210 if sign {
211 (y, o)
212 } else {
213 (-y, o.reverse())
214 }
215 } else {
216 let mut exponent = i32::saturating_from(x.floor_log_base_2_abs());
217 if exponent >= Float::MAX_EXPONENT {
218 return match (sign, rm) {
219 (true, Up | Ceiling | Nearest) => (Float::INFINITY, Greater),
220 (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
221 (false, Up | Floor | Nearest) => (Float::NEGATIVE_INFINITY, Less),
222 (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
223 (_, Exact) => panic!("Inexact conversion from Rational to Float"),
224 };
225 }
226 let (significand, o) =
227 Integer::rounding_from(x << (i128::exact_from(prec) - i128::from(exponent) - 1), rm);
228 let sign = significand >= 0;
229 let mut significand = significand.unsigned_abs();
230 let away_from_0 = if sign { Greater } else { Less };
231 if o == away_from_0 && significand.is_power_of_2() {
232 exponent += 1;
233 if exponent >= Float::MAX_EXPONENT {
234 return if sign {
235 (Float::INFINITY, Greater)
236 } else {
237 (Float::NEGATIVE_INFINITY, Less)
238 };
239 }
240 }
241 exponent += 1;
242 if exponent < Float::MIN_EXPONENT {
243 assert!(rm != Exact, "Inexact conversion from Rational to Float");
244 return if rm == Nearest
245 && exponent == Float::MIN_EXPONENT - 1
246 && (o == away_from_0.reverse() || !significand.is_power_of_2())
247 {
248 if sign {
249 (Float::min_positive_value_prec(prec), Greater)
250 } else {
251 (-Float::min_positive_value_prec(prec), Less)
252 }
253 } else {
254 match (sign, rm) {
255 (true, Up | Ceiling) => (Float::min_positive_value_prec(prec), Greater),
256 (true, Floor | Down | Nearest) => (Float::ZERO, Less),
257 (false, Up | Floor) => (-Float::min_positive_value_prec(prec), Less),
258 (false, Ceiling | Down | Nearest) => (Float::NEGATIVE_ZERO, Greater),
259 (_, Exact) => unreachable!(),
260 }
261 };
262 }
263 significand <<= significand
264 .significant_bits()
265 .neg_mod_power_of_2(Limb::LOG_WIDTH);
266 let target_bits = prec
267 .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
268 .0;
269 let current_bits = significand_bits(&significand);
270 if current_bits > target_bits {
271 significand >>= current_bits - target_bits;
272 }
273 (
274 Float(Finite {
275 sign,
276 exponent,
277 precision: prec,
278 significand,
279 }),
280 o,
281 )
282 }
283}}
284
285pub_test! {from_rational_prec_round_ref_using_div(
286 x: &Rational,
287 prec: u64,
288 mut rm: RoundingMode,
289) -> (Float, Ordering) {
290 let sign = *x >= 0;
291 if !sign {
292 rm.neg_assign();
293 }
294 let (n, d) = x.numerator_and_denominator_ref();
295 let is_zero = *n == 0;
296 let (f, o) = match (
297 if is_zero {
298 None
299 } else {
300 n.checked_log_base_2()
301 },
302 d.checked_log_base_2(),
303 ) {
304 (Some(log_n), Some(log_d)) => Float::power_of_2_prec_round(
305 i64::saturating_from(i128::from(log_n) - i128::from(log_d)),
306 prec,
307 rm,
308 ),
309 (None, Some(log_d)) => {
310 let (mut f, mut o) = from_natural_prec_round_zero_exponent_ref(n, prec, rm);
311 o = f.shr_prec_round_assign_helper(
312 i128::from(log_d) - i128::from(n.significant_bits()),
313 prec,
314 rm,
315 o,
316 );
317 (f, o)
318 }
319 (Some(log_n), None) => {
320 let (mut f, mut o) =
321 from_natural_zero_exponent_ref(d).reciprocal_prec_round(prec, rm);
322 o = f.shl_prec_round_assign_helper(
323 i128::from(log_n) - i128::from(d.significant_bits()),
324 prec,
325 rm,
326 o,
327 );
328 (f, o)
329 }
330 (None, None) => {
331 let (mut f, mut o) = from_natural_zero_exponent_ref(n).div_prec_round(
332 from_natural_zero_exponent_ref(d),
333 prec,
334 rm,
335 );
336 o = f.shl_prec_round_assign_helper(
337 i128::from(n.significant_bits()) - i128::from(d.significant_bits()),
338 prec,
339 rm,
340 o,
341 );
342 (f, o)
343 }
344 };
345 if sign {
346 (f, o)
347 } else {
348 (-f, o.reverse())
349 }
350}}
351
352const FROM_RATIONAL_THRESHOLD: u64 = 100;
353
354impl Float {
355 /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by value. If the [`Float`]
356 /// is nonzero, it has the specified precision. If rounding is needed, the specified rounding
357 /// mode is used. An [`Ordering`] is also returned, indicating whether the returned value is
358 /// less than, equal to, or greater than the original value.
359 ///
360 /// If you're only using [`Nearest`], try using [`Float::from_rational_prec`] instead.
361 ///
362 /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
363 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
364 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
365 /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
366 /// function overflows to $-\infty$ if `rm` is `Floor`, `Up`, or `Nearest`, and rounds up to
367 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
368 /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
369 /// underflows to positive zero if `rm` is `Floor` or `Down`, rounds up to $2^{-2^{30}}$ if
370 /// `rm` is `Ceiling` or `Up`, underflows to positive zero if `rm` is `Nearest` and the
371 /// [`Rational`] rounds to a value less than or equal to $2^{-2^{30}-1}$, and rounds up to
372 /// $2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value greater than
373 /// $2^{-2^{30}-1}$.
374 /// - If the [`Rational`] rounds to a negative value greater than $-2^{-2^{30}}$), this function
375 /// underflows to negative zero if `rm` is `Ceiling` or `Down`, rounds down to $-2^{-2^{30}}$
376 /// if `rm` is `Floor` or `Up`, underflows to negative zero if `rm` is `Nearest` and the
377 /// [`Rational`] rounds to a value greater than or equal to $-2^{-2^{30}-1}$, and rounds down
378 /// to $-2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value less than
379 /// $-2^{-2^{30}-1}$.
380 ///
381 /// # Worst-case complexity
382 /// $T(n) = O(n)$
383 ///
384 /// $M(n) = O(n)$
385 ///
386 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(n.significant_bits(), prec)`.
387 ///
388 /// # Panics
389 /// Panics if `prec` is zero, or if `rm` is exact and the `Rational` cannot be exactly
390 /// represented with the specified precision.
391 ///
392 /// # Examples
393 /// ```
394 /// use malachite_base::rounding_modes::RoundingMode::*;
395 /// use malachite_float::Float;
396 /// use malachite_q::Rational;
397 /// use std::cmp::Ordering::*;
398 ///
399 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Floor);
400 /// assert_eq!(x.to_string(), "0.333");
401 /// assert_eq!(x.get_prec(), Some(10));
402 /// assert_eq!(o, Less);
403 ///
404 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Ceiling);
405 /// assert_eq!(x.to_string(), "0.3335");
406 /// assert_eq!(x.get_prec(), Some(10));
407 /// assert_eq!(o, Greater);
408 ///
409 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(1, 3), 10, Nearest);
410 /// assert_eq!(x.to_string(), "0.3335");
411 /// assert_eq!(x.get_prec(), Some(10));
412 /// assert_eq!(o, Greater);
413 ///
414 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Floor);
415 /// assert_eq!(x.to_string(), "-0.3335");
416 /// assert_eq!(x.get_prec(), Some(10));
417 /// assert_eq!(o, Less);
418 ///
419 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Ceiling);
420 /// assert_eq!(x.to_string(), "-0.333");
421 /// assert_eq!(x.get_prec(), Some(10));
422 /// assert_eq!(o, Greater);
423 ///
424 /// let (x, o) = Float::from_rational_prec_round(Rational::from_signeds(-1, 3), 10, Nearest);
425 /// assert_eq!(x.to_string(), "-0.3335");
426 /// assert_eq!(x.get_prec(), Some(10));
427 /// assert_eq!(o, Less);
428 /// ```
429 #[inline]
430 pub fn from_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
431 if max(x.significant_bits(), prec) < FROM_RATIONAL_THRESHOLD {
432 from_rational_prec_round_direct(x, prec, rm)
433 } else {
434 from_rational_prec_round_using_div(x, prec, rm)
435 }
436 }
437
438 /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by value. If the [`Float`]
439 /// is nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
440 /// whether the returned value is less than, equal to, or greater than the original value.
441 ///
442 /// If the [`Rational`] is dyadic (its denominator is a power of 2), then you can convert it to
443 /// a [`Float`] using `try_from` instead. The precision of the resulting [`Float`] will be the
444 /// number of significant bits of the [`Rational`]'s numerator.
445 ///
446 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
447 /// as well as a precision, try [`Float::from_rational_prec_round`].
448 ///
449 /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
450 /// function overflows to $\infty$.
451 /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
452 /// function overflows to $-\infty$.
453 /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
454 /// underflows to positive zero if the [`Rational`] rounds to a value less than or equal to
455 /// $2^{-2^{30}-1}$ and rounds up to $2^{-2^{30}}$ if the [`Rational`] rounds to a value
456 /// greater than $2^{-2^{30}-1}$.
457 /// - If the [`Rational`] rounds to a negative value greater than $2^{-2^{30}}$), this function
458 /// underflows to negative zero if the [`Rational`] rounds to a value greater than or equal to
459 /// $-2^{-2^{30}-1}$ and rounds down to $-2^{-2^{30}}$ if the [`Rational`] rounds to a value
460 /// less than $-2^{-2^{30}-1}$.
461 ///
462 /// # Panics
463 /// Panics if `prec` is zero.
464 ///
465 /// # Worst-case complexity
466 /// $T(n) = O(n \log n \log\log n)$
467 ///
468 /// $M(n) = O(n \log n)$
469 ///
470 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(), prec)`.
471 ///
472 /// # Examples
473 /// ```
474 /// use malachite_base::num::basic::traits::Zero;
475 /// use malachite_float::Float;
476 /// use malachite_q::Rational;
477 /// use std::cmp::Ordering::*;
478 ///
479 /// let (x, o) = Float::from_rational_prec(Rational::ZERO, 10);
480 /// assert_eq!(x.to_string(), "0.0");
481 /// assert_eq!(o, Equal);
482 ///
483 /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(1, 3), 10);
484 /// assert_eq!(x.to_string(), "0.3335");
485 /// assert_eq!(x.get_prec(), Some(10));
486 /// assert_eq!(o, Greater);
487 ///
488 /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(1, 3), 100);
489 /// assert_eq!(x.to_string(), "0.3333333333333333333333333333335");
490 /// assert_eq!(x.get_prec(), Some(100));
491 /// assert_eq!(o, Greater);
492 ///
493 /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(-1, 3), 10);
494 /// assert_eq!(x.to_string(), "-0.3335");
495 /// assert_eq!(x.get_prec(), Some(10));
496 /// assert_eq!(o, Less);
497 ///
498 /// let (x, o) = Float::from_rational_prec(Rational::from_signeds(-1, 3), 100);
499 /// assert_eq!(x.to_string(), "-0.3333333333333333333333333333335");
500 /// assert_eq!(x.get_prec(), Some(100));
501 /// assert_eq!(o, Less);
502 /// ```
503 #[inline]
504 pub fn from_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
505 Self::from_rational_prec_round(x, prec, Nearest)
506 }
507
508 /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by reference. If the
509 /// [`Float`] is nonzero, it has the specified precision. If rounding is needed, the specified
510 /// rounding mode is used. An [`Ordering`] is also returned, indicating whether the returned
511 /// value is less than, equal to, or greater than the original value.
512 ///
513 /// If you're only using [`Nearest`], try using [`Float::from_rational_prec_ref`] instead.
514 ///
515 /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
516 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
517 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
518 /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
519 /// function overflows to $-\infty$ if `rm` is `Floor`, `Up`, or `Nearest`, and rounds up to
520 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
521 /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
522 /// underflows to positive zero if `rm` is `Floor` or `Down`, rounds up to $2^{-2^{30}}$ if
523 /// `rm` is `Ceiling` or `Up`, underflows to positive zero if `rm` is `Nearest` and the
524 /// [`Rational`] rounds to a value less than or equal to $2^{-2^{30}-1}$, and rounds up to
525 /// $2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value greater than
526 /// $2^{-2^{30}-1}$.
527 /// - If the [`Rational`] rounds to a negative value greater than $-2^{-2^{30}}$), this function
528 /// underflows to negative zero if `rm` is `Ceiling` or `Down`, rounds down to $-2^{-2^{30}}$
529 /// if `rm` is `Floor` or `Up`, underflows to negative zero if `rm` is `Nearest` and the
530 /// [`Rational`] rounds to a value greater than or equal to $-2^{-2^{30}-1}$, and rounds down
531 /// to $-2^{-2^{30}}$ if `rm` is `Nearest` and the [`Rational`] rounds to a value less than
532 /// $-2^{-2^{30}-1}$.
533 ///
534 /// # Worst-case complexity
535 /// $T(n) = O(n \log n \log\log n)$
536 ///
537 /// $M(n) = O(n \log n)$
538 ///
539 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(), prec)`.
540 ///
541 /// # Panics
542 /// Panics if `prec` is zero, or if `rm` is exact and the `Rational` cannot be exactly
543 /// represented with the specified precision.
544 ///
545 /// # Examples
546 /// ```
547 /// use malachite_base::rounding_modes::RoundingMode::*;
548 /// use malachite_float::Float;
549 /// use malachite_q::Rational;
550 /// use std::cmp::Ordering::*;
551 ///
552 /// let (x, o) = Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Floor);
553 /// assert_eq!(x.to_string(), "0.333");
554 /// assert_eq!(x.get_prec(), Some(10));
555 /// assert_eq!(o, Less);
556 ///
557 /// let (x, o) =
558 /// Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Ceiling);
559 /// assert_eq!(x.to_string(), "0.3335");
560 /// assert_eq!(x.get_prec(), Some(10));
561 /// assert_eq!(o, Greater);
562 ///
563 /// let (x, o) =
564 /// Float::from_rational_prec_round_ref(&Rational::from_signeds(1, 3), 10, Nearest);
565 /// assert_eq!(x.to_string(), "0.3335");
566 /// assert_eq!(x.get_prec(), Some(10));
567 /// assert_eq!(o, Greater);
568 ///
569 /// let (x, o) = Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Floor);
570 /// assert_eq!(x.to_string(), "-0.3335");
571 /// assert_eq!(x.get_prec(), Some(10));
572 /// assert_eq!(o, Less);
573 ///
574 /// let (x, o) =
575 /// Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Ceiling);
576 /// assert_eq!(x.to_string(), "-0.333");
577 /// assert_eq!(x.get_prec(), Some(10));
578 /// assert_eq!(o, Greater);
579 ///
580 /// let (x, o) =
581 /// Float::from_rational_prec_round_ref(&Rational::from_signeds(-1, 3), 10, Nearest);
582 /// assert_eq!(x.to_string(), "-0.3335");
583 /// assert_eq!(x.get_prec(), Some(10));
584 /// assert_eq!(o, Less);
585 /// ```
586 #[inline]
587 pub fn from_rational_prec_round_ref(
588 x: &Rational,
589 prec: u64,
590 rm: RoundingMode,
591 ) -> (Self, Ordering) {
592 if max(x.significant_bits(), prec) < FROM_RATIONAL_THRESHOLD {
593 from_rational_prec_round_ref_direct(x, prec, rm)
594 } else {
595 from_rational_prec_round_ref_using_div(x, prec, rm)
596 }
597 }
598
599 /// Converts a [`Rational`] to a [`Float`], taking the [`Rational`] by reference. If the
600 /// [`Float`] is nonzero, it has the specified precision. An [`Ordering`] is also returned,
601 /// indicating whether the returned value is less than, equal to, or greater than the original
602 /// value.
603 ///
604 /// If the [`Rational`] is dyadic (its denominator is a power of 2), then you can convert it to
605 /// a [`Float`] using `try_from` instead. The precision of the resulting [`Float`] will be the
606 /// number of significant bits of the [`Rational`]'s numerator.
607 ///
608 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
609 /// as well as a precision, try [`Float::from_rational_prec_round_ref`].
610 ///
611 /// - If the [`Rational`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
612 /// function overflows to $\infty$.
613 /// - If the [`Rational`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this
614 /// function overflows to $-\infty$.
615 /// - If the [`Rational`] rounds to a positive value less than $2^{-2^{30}}$), this function
616 /// underflows to positive zero if the [`Rational`] rounds to a value less than or equal to
617 /// $2^{-2^{30}-1}$ and rounds up to $2^{-2^{30}}$ if the [`Rational`] rounds to a value
618 /// greater than $2^{-2^{30}-1}$.
619 /// - If the [`Rational`] rounds to a negative value greater than $2^{-2^{30}}$), this function
620 /// underflows to negative zero if the [`Rational`] rounds to a value greater than or equal to
621 /// $-2^{-2^{30}-1}$ and rounds down to $-2^{-2^{30}}$ if the [`Rational`] rounds to a value
622 /// less than $-2^{-2^{30}-1}$.
623 ///
624 /// # Worst-case complexity
625 /// $T(n) = O(n \log n \log\log n)$
626 ///
627 /// $M(n) = O(n \log n)$
628 ///
629 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(), prec)`.
630 ///
631 /// # Panics
632 /// Panics if `prec` is zero.
633 ///
634 /// # Examples
635 /// ```
636 /// use malachite_base::num::basic::traits::Zero;
637 /// use malachite_float::Float;
638 /// use malachite_q::Rational;
639 /// use std::cmp::Ordering::*;
640 ///
641 /// let (x, o) = Float::from_rational_prec_ref(&Rational::ZERO, 10);
642 /// assert_eq!(x.to_string(), "0.0");
643 /// assert_eq!(o, Equal);
644 ///
645 /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(1, 3), 10);
646 /// assert_eq!(x.to_string(), "0.3335");
647 /// assert_eq!(x.get_prec(), Some(10));
648 /// assert_eq!(o, Greater);
649 ///
650 /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(1, 3), 100);
651 /// assert_eq!(x.to_string(), "0.3333333333333333333333333333335");
652 /// assert_eq!(x.get_prec(), Some(100));
653 /// assert_eq!(o, Greater);
654 ///
655 /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(-1, 3), 10);
656 /// assert_eq!(x.to_string(), "-0.3335");
657 /// assert_eq!(x.get_prec(), Some(10));
658 /// assert_eq!(o, Less);
659 ///
660 /// let (x, o) = Float::from_rational_prec_ref(&Rational::from_signeds(-1, 3), 100);
661 /// assert_eq!(x.to_string(), "-0.3333333333333333333333333333335");
662 /// assert_eq!(x.get_prec(), Some(100));
663 /// assert_eq!(o, Less);
664 /// ```
665 #[inline]
666 pub fn from_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
667 Self::from_rational_prec_round_ref(x, prec, Nearest)
668 }
669}
670
671impl TryFrom<Rational> for Float {
672 type Error = FloatConversionError;
673
674 /// Converts a [`Rational`] to an [`Float`], taking the [`Rational`] by value. If the
675 /// [`Rational`]'s denominator is not a power of 2, or if the [`Rational`] is too far from zero
676 /// or too close to zero to be represented as a [`Float`], an error is returned.
677 ///
678 /// The [`Float`]'s precision is the minimum number of bits needed to exactly represent the
679 /// [`Rational`].
680 ///
681 /// - If the [`Rational`] is greater than or equal to $2^{2^{30}-1}$), this function returns an
682 /// overflow error.
683 /// - If the [`Rational`] is less than or equal to $-2^{2^{30}-1}$), this function returns an
684 /// overflow error.
685 /// - If the [`Rational`] is positive and less than $2^{-2^{30}}$), this function returns an
686 /// underflow error.
687 /// - If the [`Rational`] is negative and greater than $-2^{-2^{30}}$), this function returns an
688 /// underflow error.
689 ///
690 /// # Worst-case complexity
691 /// $T(n) = O(n)$
692 ///
693 /// $M(n) = O(1)$
694 ///
695 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
696 ///
697 /// # Examples
698 /// ```
699 /// use malachite_base::num::basic::traits::Zero;
700 /// use malachite_float::Float;
701 /// use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
702 /// use malachite_q::Rational;
703 ///
704 /// assert_eq!(Float::try_from(Rational::ZERO).unwrap(), 0);
705 /// assert_eq!(
706 /// Float::try_from(Rational::from_signeds(1, 8)).unwrap(),
707 /// 0.125
708 /// );
709 /// assert_eq!(
710 /// Float::try_from(Rational::from_signeds(-1, 8)).unwrap(),
711 /// -0.125
712 /// );
713 ///
714 /// assert_eq!(
715 /// Float::try_from(Rational::from_signeds(1, 3)),
716 /// Err(FloatConversionError::Inexact)
717 /// );
718 /// assert_eq!(
719 /// Float::try_from(Rational::from_signeds(-1, 3)),
720 /// Err(FloatConversionError::Inexact)
721 /// );
722 /// ```
723 fn try_from(x: Rational) -> Result<Self, Self::Error> {
724 if x == 0u32 {
725 return Ok(Self::ZERO);
726 }
727 if let Some(log_denominator) = x.denominator_ref().checked_log_base_2() {
728 let exponent = i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1);
729 if exponent > Self::MAX_EXPONENT {
730 return Err(FloatConversionError::Overflow);
731 } else if exponent < Self::MIN_EXPONENT {
732 return Err(FloatConversionError::Underflow);
733 }
734 let n = Integer::from_sign_and_abs(x >= 0u32, x.into_numerator());
735 let n_bits = n.significant_bits();
736 Ok(from_integer_zero_exponent(n) >> (i128::from(log_denominator) - i128::from(n_bits)))
737 } else {
738 Err(FloatConversionError::Inexact)
739 }
740 }
741}
742
743impl TryFrom<&Rational> for Float {
744 type Error = FloatConversionError;
745
746 /// Converts a [`Rational`] to an [`Float`], taking the [`Rational`] by reference. If the
747 /// [`Rational`]'s denominator is not a power of 2, or if the [`Rational`] is too far from zero
748 /// or too close to zero to be represented as a [`Float`], an error is returned.
749 ///
750 /// The [`Float`]'s precision is the minimum number of bits needed to exactly represent the
751 /// [`Rational`].
752 ///
753 /// - If the [`Rational`] is greater than or equal to $2^{2^{30}-1}$), this function returns an
754 /// overflow error.
755 /// - If the [`Rational`] is less than or equal to $-2^{2^{30}-1}$), this function returns an
756 /// overflow error.
757 /// - If the [`Rational`] is positive and less than $2^{-2^{30}}$), this function returns an
758 /// underflow error.
759 /// - If the [`Rational`] is negative and greater than $-2^{-2^{30}}$), this function returns an
760 /// underflow error.
761 ///
762 /// # Worst-case complexity
763 /// $T(n) = O(n)$
764 ///
765 /// $M(n) = O(n)$
766 ///
767 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
768 ///
769 /// # Examples
770 /// ```
771 /// use malachite_base::num::basic::traits::Zero;
772 /// use malachite_float::Float;
773 /// use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
774 /// use malachite_q::Rational;
775 ///
776 /// assert_eq!(Float::try_from(&Rational::ZERO).unwrap(), 0);
777 /// assert_eq!(
778 /// Float::try_from(&Rational::from_signeds(1, 8)).unwrap(),
779 /// 0.125
780 /// );
781 /// assert_eq!(
782 /// Float::try_from(&Rational::from_signeds(-1, 8)).unwrap(),
783 /// -0.125
784 /// );
785 ///
786 /// assert_eq!(
787 /// Float::try_from(&Rational::from_signeds(1, 3)),
788 /// Err(FloatConversionError::Inexact)
789 /// );
790 /// assert_eq!(
791 /// Float::try_from(&Rational::from_signeds(-1, 3)),
792 /// Err(FloatConversionError::Inexact)
793 /// );
794 /// ```
795 fn try_from(x: &Rational) -> Result<Self, Self::Error> {
796 if *x == 0u32 {
797 return Ok(Self::ZERO);
798 }
799 if let Some(log_denominator) = x.denominator_ref().checked_log_base_2() {
800 let exponent = i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1);
801 if exponent > Self::MAX_EXPONENT {
802 return Err(FloatConversionError::Overflow);
803 } else if exponent < Self::MIN_EXPONENT {
804 return Err(FloatConversionError::Underflow);
805 }
806 let n = x.numerator_ref();
807 let n_bits = n.significant_bits();
808 let mut n = from_natural_zero_exponent_ref(n);
809 if *x < 0 {
810 n.neg_assign();
811 }
812 Ok(n >> (i128::from(log_denominator) - i128::from(n_bits)))
813 } else {
814 Err(FloatConversionError::Inexact)
815 }
816 }
817}
818
819impl ConvertibleFrom<&Rational> for Float {
820 /// Determines whether a [`Rational`] can be converted to an [`Float`], taking the [`Rational`]
821 /// by reference.
822 ///
823 /// The [`Rational`]s that are convertible to [`Float`]s are precisely those whose denominators
824 /// are powers of two, and would not overflow or underflow.
825 ///
826 /// # Worst-case complexity
827 /// $T(n) = O(n)$
828 ///
829 /// $M(n) = O(1)$
830 ///
831 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
832 ///
833 /// # Examples
834 /// ```
835 /// use malachite_base::num::basic::traits::Zero;
836 /// use malachite_base::num::conversion::traits::ConvertibleFrom;
837 /// use malachite_float::Float;
838 /// use malachite_q::Rational;
839 ///
840 /// assert_eq!(Float::convertible_from(&Rational::ZERO), true);
841 /// assert_eq!(Float::convertible_from(&Rational::from_signeds(3, 8)), true);
842 /// assert_eq!(
843 /// Float::convertible_from(&Rational::from_signeds(-3, 8)),
844 /// true
845 /// );
846 ///
847 /// assert_eq!(
848 /// Float::convertible_from(&Rational::from_signeds(1, 3)),
849 /// false
850 /// );
851 /// assert_eq!(
852 /// Float::convertible_from(&Rational::from_signeds(-1, 3)),
853 /// false
854 /// );
855 /// ```
856 #[inline]
857 fn convertible_from(x: &Rational) -> bool {
858 *x == 0
859 || x.denominator_ref().is_power_of_2()
860 && (Self::MIN_EXPONENT..=Self::MAX_EXPONENT)
861 .contains(&i32::saturating_from(x.floor_log_base_2_abs()).saturating_add(1))
862 }
863}