malachite_float/conversion/from_integer.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::conversion::from_natural::{
10 from_natural_prec_round_zero_exponent, from_natural_zero_exponent,
11};
12use crate::Float;
13use core::cmp::Ordering;
14use malachite_base::num::arithmetic::traits::{FloorLogBase2, UnsignedAbs};
15use malachite_base::num::conversion::traits::{ConvertibleFrom, SaturatingFrom};
16use malachite_base::rounding_modes::RoundingMode::{self, *};
17use malachite_nz::integer::Integer;
18use malachite_q::conversion::primitive_float_from_rational::FloatConversionError;
19
20pub(crate) fn from_integer_zero_exponent(n: Integer) -> Float {
21 let sign = n >= 0;
22 let f = from_natural_zero_exponent(n.unsigned_abs());
23 if sign {
24 f
25 } else {
26 -f
27 }
28}
29
30pub(crate) fn from_integer_prec_round_zero_exponent(
31 x: Integer,
32 prec: u64,
33 rm: RoundingMode,
34) -> (Float, Ordering) {
35 let sign = x >= 0;
36 let (f, o) =
37 from_natural_prec_round_zero_exponent(x.unsigned_abs(), prec, if sign { rm } else { -rm });
38 if sign {
39 (f, o)
40 } else {
41 (-f, o.reverse())
42 }
43}
44
45impl Float {
46 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value. If the [`Float`] is
47 /// nonzero, it has the specified precision. If rounding is needed, the specified rounding mode
48 /// is used. An [`Ordering`] is also returned, indicating whether the returned value is less
49 /// than, equal to, or greater than the original value.
50 ///
51 /// If you're only using [`Nearest`], try using [`Float::from_integer_prec`] instead.
52 ///
53 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
54 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
55 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
56 /// - If the [`Integer`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this function
57 /// overflows to $-\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds up to
58 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
59 ///
60 /// # Worst-case complexity
61 /// $T(m,n) = O(\max(m,n))$
62 ///
63 /// $M(n) = O(n)$
64 ///
65 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
66 /// `prec`.
67 ///
68 /// # Panics
69 /// Panics if `prec` is zero, or if `rm` is exact and the `Integer` cannot be exactly
70 /// represented with the specified precision.
71 ///
72 /// # Examples
73 /// ```
74 /// use malachite_base::num::basic::traits::Zero;
75 /// use malachite_base::rounding_modes::RoundingMode::*;
76 /// use malachite_float::Float;
77 /// use malachite_nz::integer::Integer;
78 /// use std::cmp::Ordering::*;
79 ///
80 /// let (x, o) = Float::from_integer_prec_round(Integer::ZERO, 10, Exact);
81 /// assert_eq!(x.to_string(), "0.0");
82 /// assert_eq!(o, Equal);
83 ///
84 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 20, Exact);
85 /// assert_eq!(x.to_string(), "123.0");
86 /// assert_eq!(x.get_prec(), Some(20));
87 /// assert_eq!(o, Equal);
88 ///
89 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 4, Floor);
90 /// assert_eq!(x.to_string(), "1.2e2");
91 /// assert_eq!(x.get_prec(), Some(4));
92 /// assert_eq!(o, Less);
93 ///
94 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 4, Ceiling);
95 /// assert_eq!(x.to_string(), "1.3e2");
96 /// assert_eq!(x.get_prec(), Some(4));
97 /// assert_eq!(o, Greater);
98 ///
99 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 20, Exact);
100 /// assert_eq!(x.to_string(), "-123.0");
101 /// assert_eq!(x.get_prec(), Some(20));
102 /// assert_eq!(o, Equal);
103 ///
104 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 4, Floor);
105 /// assert_eq!(x.to_string(), "-1.3e2");
106 /// assert_eq!(x.get_prec(), Some(4));
107 /// assert_eq!(o, Less);
108 ///
109 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 4, Ceiling);
110 /// assert_eq!(x.to_string(), "-1.2e2");
111 /// assert_eq!(x.get_prec(), Some(4));
112 /// assert_eq!(o, Greater);
113 /// ```
114 #[inline]
115 pub fn from_integer_prec_round(x: Integer, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
116 let sign = x >= 0;
117 let (f, o) =
118 Float::from_natural_prec_round(x.unsigned_abs(), prec, if sign { rm } else { -rm });
119 if sign {
120 (f, o)
121 } else {
122 (-f, o.reverse())
123 }
124 }
125
126 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference. If the
127 /// [`Float`] is nonzero, it has the specified precision. If rounding is needed, the specified
128 /// rounding mode is used. An [`Ordering`] is also returned, indicating whether the returned
129 /// value is less than, equal to, or greater than the original value.
130 ///
131 /// If you're only using [`Nearest`], try using [`Float::from_integer_prec_ref`] instead.
132 ///
133 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
134 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
135 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
136 /// - If the [`Integer`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this function
137 /// overflows to $-\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds up to
138 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
139 ///
140 /// # Worst-case complexity
141 /// $T(m,n) = O(\max(m,n))$
142 ///
143 /// $M(n) = O(n)$
144 ///
145 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
146 /// `prec`.
147 ///
148 /// # Panics
149 /// Panics if `prec` is zero, or if `rm` is exact and the `Integer` cannot be exactly
150 /// represented with the specified precision.
151 ///
152 /// # Examples
153 /// ```
154 /// use malachite_base::num::basic::traits::Zero;
155 /// use malachite_base::rounding_modes::RoundingMode::*;
156 /// use malachite_float::Float;
157 /// use malachite_nz::integer::Integer;
158 /// use std::cmp::Ordering::*;
159 ///
160 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::ZERO, 10, Exact);
161 /// assert_eq!(x.to_string(), "0.0");
162 /// assert_eq!(o, Equal);
163 ///
164 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 20, Exact);
165 /// assert_eq!(x.to_string(), "123.0");
166 /// assert_eq!(x.get_prec(), Some(20));
167 /// assert_eq!(o, Equal);
168 ///
169 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 4, Floor);
170 /// assert_eq!(x.to_string(), "1.2e2");
171 /// assert_eq!(x.get_prec(), Some(4));
172 /// assert_eq!(o, Less);
173 ///
174 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 4, Ceiling);
175 /// assert_eq!(x.to_string(), "1.3e2");
176 /// assert_eq!(x.get_prec(), Some(4));
177 /// assert_eq!(o, Greater);
178 ///
179 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 20, Exact);
180 /// assert_eq!(x.to_string(), "-123.0");
181 /// assert_eq!(x.get_prec(), Some(20));
182 /// assert_eq!(o, Equal);
183 ///
184 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 4, Floor);
185 /// assert_eq!(x.to_string(), "-1.3e2");
186 /// assert_eq!(x.get_prec(), Some(4));
187 /// assert_eq!(o, Less);
188 ///
189 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 4, Ceiling);
190 /// assert_eq!(x.to_string(), "-1.2e2");
191 /// assert_eq!(x.get_prec(), Some(4));
192 /// assert_eq!(o, Greater);
193 /// ```
194 #[inline]
195 pub fn from_integer_prec_round_ref(
196 x: &Integer,
197 prec: u64,
198 rm: RoundingMode,
199 ) -> (Float, Ordering) {
200 let sign = *x >= 0;
201 let (f, o) = Float::from_natural_prec_round_ref(
202 x.unsigned_abs_ref(),
203 prec,
204 if sign { rm } else { -rm },
205 );
206 if sign {
207 (f, o)
208 } else {
209 (-f, o.reverse())
210 }
211 }
212
213 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value. If the [`Float`] is
214 /// nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
215 /// whether the returned value is less than, equal to, or greater than the original value.
216 ///
217 /// If you want the [`Float`]'s precision to be equal to the [`Integer`]'s number of significant
218 /// bits, try just using `Float::try_from` instead.
219 ///
220 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
221 /// as well as a precision, try [`Float::from_integer_prec_round`].
222 ///
223 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
224 /// function overflows to $\infty$.
225 /// - If the [`Integer`] rounds to a value less than or equal to -$2^{2^{30}-1}$), this function
226 /// overflows to $\infty$.
227 ///
228 /// # Worst-case complexity
229 /// $T(m,n) = O(\max(m,n))$
230 ///
231 /// $M(n) = O(n)$
232 ///
233 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
234 /// `prec`.
235 ///
236 /// # Panics
237 /// Panics if `prec` is zero.
238 ///
239 /// # Examples
240 /// ```
241 /// use malachite_base::num::basic::traits::Zero;
242 /// use malachite_float::Float;
243 /// use malachite_nz::integer::Integer;
244 /// use std::cmp::Ordering::*;
245 ///
246 /// let (x, o) = Float::from_integer_prec(Integer::ZERO, 10);
247 /// assert_eq!(x.to_string(), "0.0");
248 /// assert_eq!(o, Equal);
249 ///
250 /// let (x, o) = Float::from_integer_prec(Integer::from(123), 20);
251 /// assert_eq!(x.to_string(), "123.0");
252 /// assert_eq!(x.get_prec(), Some(20));
253 /// assert_eq!(o, Equal);
254 ///
255 /// let (x, o) = Float::from_integer_prec(Integer::from(123), 4);
256 /// assert_eq!(x.to_string(), "1.2e2");
257 /// assert_eq!(x.get_prec(), Some(4));
258 /// assert_eq!(o, Less);
259 ///
260 /// let (x, o) = Float::from_integer_prec(Integer::from(-123), 20);
261 /// assert_eq!(x.to_string(), "-123.0");
262 /// assert_eq!(x.get_prec(), Some(20));
263 /// assert_eq!(o, Equal);
264 ///
265 /// let (x, o) = Float::from_integer_prec(Integer::from(-123), 4);
266 /// assert_eq!(x.to_string(), "-1.2e2");
267 /// assert_eq!(x.get_prec(), Some(4));
268 /// assert_eq!(o, Greater);
269 /// ```
270 #[inline]
271 pub fn from_integer_prec(x: Integer, prec: u64) -> (Float, Ordering) {
272 Float::from_integer_prec_round(x, prec, Nearest)
273 }
274
275 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference. If the
276 /// [`Float`] is nonzero, it has the specified precision. An [`Ordering`] is also returned,
277 /// indicating whether the returned value is less than, equal to, or greater than the original
278 /// value.
279 ///
280 /// If you want the [`Float`]'s precision to be equal to the [`Integer`]'s number of significant
281 /// bits, try just using `Float::try_from` instead.
282 ///
283 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
284 /// as well as a precision, try [`Float::from_integer_prec_round_ref`].
285 ///
286 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
287 /// function overflows to $\infty$.
288 /// - If the [`Integer`] rounds to a value less than or equal to -$2^{2^{30}-1}$), this function
289 /// overflows to $\infty$.
290 ///
291 /// # Worst-case complexity
292 /// $T(m,n) = O(\max(m,n))$
293 ///
294 /// $M(n) = O(n)$
295 ///
296 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
297 /// `prec`.
298 ///
299 /// # Panics
300 /// Panics if `prec` is zero.
301 ///
302 /// # Examples
303 /// ```
304 /// use malachite_base::num::basic::traits::Zero;
305 /// use malachite_float::Float;
306 /// use malachite_nz::integer::Integer;
307 /// use std::cmp::Ordering::*;
308 ///
309 /// let (x, o) = Float::from_integer_prec_ref(&Integer::ZERO, 10);
310 /// assert_eq!(x.to_string(), "0.0");
311 /// assert_eq!(o, Equal);
312 ///
313 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(123), 20);
314 /// assert_eq!(x.to_string(), "123.0");
315 /// assert_eq!(x.get_prec(), Some(20));
316 /// assert_eq!(o, Equal);
317 ///
318 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(123), 4);
319 /// assert_eq!(x.to_string(), "1.2e2");
320 /// assert_eq!(x.get_prec(), Some(4));
321 /// assert_eq!(o, Less);
322 ///
323 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(-123), 20);
324 /// assert_eq!(x.to_string(), "-123.0");
325 /// assert_eq!(x.get_prec(), Some(20));
326 /// assert_eq!(o, Equal);
327 ///
328 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(-123), 4);
329 /// assert_eq!(x.to_string(), "-1.2e2");
330 /// assert_eq!(x.get_prec(), Some(4));
331 /// assert_eq!(o, Greater);
332 /// ```
333 #[inline]
334 pub fn from_integer_prec_ref(x: &Integer, prec: u64) -> (Float, Ordering) {
335 let sign = *x >= 0;
336 let (f, o) = Float::from_natural_prec_ref(x.unsigned_abs_ref(), prec);
337 if sign {
338 (f, o)
339 } else {
340 (-f, o.reverse())
341 }
342 }
343}
344
345impl TryFrom<Integer> for Float {
346 type Error = FloatConversionError;
347
348 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value.
349 ///
350 /// If the [`Integer`] is nonzero, the precision of the [`Float`] is the minimum possible
351 /// precision to represent the [`Integer`] exactly. If you want to specify some other precision,
352 /// try [`Float::from_integer_prec`]. This may require rounding, which uses [`Nearest`] by
353 /// default. To specify a rounding mode as well as a precision, try
354 /// [`Float::from_integer_prec_round`].
355 ///
356 /// If the absolue value of the [`Integer`] is greater than or equal to $2^{2^{30}-1}$, this
357 /// function returns an overflow error.
358 ///
359 /// # Worst-case complexity
360 /// $T(n) = O(n)$
361 ///
362 /// $M(n) = O(1)$
363 ///
364 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
365 ///
366 /// # Examples
367 /// ```
368 /// use malachite_base::num::basic::traits::Zero;
369 /// use malachite_float::Float;
370 /// use malachite_nz::integer::Integer;
371 ///
372 /// assert_eq!(Float::try_from(Integer::ZERO).unwrap().to_string(), "0.0");
373 /// assert_eq!(
374 /// Float::try_from(Integer::from(123)).unwrap().to_string(),
375 /// "123.0"
376 /// );
377 /// assert_eq!(
378 /// Float::try_from(Integer::from(123)).unwrap().get_prec(),
379 /// Some(7)
380 /// );
381 /// assert_eq!(
382 /// Float::try_from(Integer::from(10)).unwrap().to_string(),
383 /// "10.0"
384 /// );
385 /// assert_eq!(
386 /// Float::try_from(Integer::from(10)).unwrap().get_prec(),
387 /// Some(3)
388 /// );
389 /// assert_eq!(
390 /// Float::try_from(Integer::from(-123)).unwrap().to_string(),
391 /// "-123.0"
392 /// );
393 /// assert_eq!(
394 /// Float::try_from(Integer::from(-123)).unwrap().get_prec(),
395 /// Some(7)
396 /// );
397 /// assert_eq!(
398 /// Float::try_from(Integer::from(-10)).unwrap().to_string(),
399 /// "-10.0"
400 /// );
401 /// assert_eq!(
402 /// Float::try_from(Integer::from(-10)).unwrap().get_prec(),
403 /// Some(3)
404 /// );
405 /// ```
406 #[inline]
407 fn try_from(n: Integer) -> Result<Float, Self::Error> {
408 let sign = n >= 0;
409 let abs = Float::try_from(n.unsigned_abs())?;
410 Ok(if sign { abs } else { -abs })
411 }
412}
413
414impl TryFrom<&Integer> for Float {
415 type Error = FloatConversionError;
416
417 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference.
418 ///
419 /// If the [`Integer`] is nonzero, the precision of the [`Float`] is the minimum possible
420 /// precision to represent the [`Integer`] exactly. If you want to specify some other precision,
421 /// try [`Float::from_integer_prec`]. This may require rounding, which uses [`Nearest`] by
422 /// default. To specify a rounding mode as well as a precision, try
423 /// [`Float::from_integer_prec_round`].
424 ///
425 /// If the absolue value of the [`Integer`] is greater than or equal to $2^{2^{30}-1}$, this
426 /// function returns an overflow error.
427 ///
428 /// # Worst-case complexity
429 /// $T(n) = O(n)$
430 ///
431 /// $M(n) = O(1)$
432 ///
433 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
434 ///
435 /// # Examples
436 /// ```
437 /// use malachite_base::num::basic::traits::Zero;
438 /// use malachite_float::Float;
439 /// use malachite_nz::integer::Integer;
440 ///
441 /// assert_eq!(Float::try_from(&Integer::ZERO).unwrap().to_string(), "0.0");
442 /// assert_eq!(
443 /// Float::try_from(&Integer::from(123)).unwrap().to_string(),
444 /// "123.0"
445 /// );
446 /// assert_eq!(
447 /// Float::try_from(&Integer::from(123)).unwrap().get_prec(),
448 /// Some(7)
449 /// );
450 /// assert_eq!(
451 /// Float::try_from(&Integer::from(10)).unwrap().to_string(),
452 /// "10.0"
453 /// );
454 /// assert_eq!(
455 /// Float::try_from(&Integer::from(10)).unwrap().get_prec(),
456 /// Some(3)
457 /// );
458 /// assert_eq!(
459 /// Float::try_from(&Integer::from(-123)).unwrap().to_string(),
460 /// "-123.0"
461 /// );
462 /// assert_eq!(
463 /// Float::try_from(&Integer::from(-123)).unwrap().get_prec(),
464 /// Some(7)
465 /// );
466 /// assert_eq!(
467 /// Float::try_from(&Integer::from(-10)).unwrap().to_string(),
468 /// "-10.0"
469 /// );
470 /// assert_eq!(
471 /// Float::try_from(&Integer::from(-10)).unwrap().get_prec(),
472 /// Some(3)
473 /// );
474 /// ```
475 #[inline]
476 fn try_from(n: &Integer) -> Result<Float, Self::Error> {
477 let sign = *n >= 0;
478 let abs = Float::try_from(n.unsigned_abs())?;
479 Ok(if sign { abs } else { -abs })
480 }
481}
482
483impl ConvertibleFrom<&Integer> for Float {
484 /// Determines whether an [`Integer`] can be converted to an [`Float`], taking the [`Integer`]
485 /// by reference.
486 ///
487 /// The [`Integer`]s that are convertible to [`Float`]s are those whose that would not overflow:
488 /// that is, those whose absolute values are less than $2^{2^{30}-1}$.
489 ///
490 /// # Worst-case complexity
491 /// $T(n) = O(n)$
492 ///
493 /// $M(n) = O(1)$
494 ///
495 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
496 ///
497 /// # Examples
498 /// ```
499 /// use malachite_base::num::basic::traits::Zero;
500 /// use malachite_base::num::conversion::traits::ConvertibleFrom;
501 /// use malachite_float::Float;
502 /// use malachite_nz::integer::Integer;
503 ///
504 /// assert_eq!(Float::convertible_from(&Integer::ZERO), true);
505 /// assert_eq!(Float::convertible_from(&Integer::from(3u8)), true);
506 /// ```
507 #[inline]
508 fn convertible_from(x: &Integer) -> bool {
509 *x == 0
510 || (Float::MIN_EXPONENT..=Float::MAX_EXPONENT).contains(
511 &i32::saturating_from(x.unsigned_abs_ref().floor_log_base_2()).saturating_add(1),
512 )
513 }
514}