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}