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