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