malachite_float/conversion/
from_primitive_int.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::InnerFloat::Finite;
11use core::cmp::Ordering;
12use malachite_base::num::basic::integers::PrimitiveInt;
13use malachite_base::num::basic::signeds::PrimitiveSigned;
14use malachite_base::num::basic::traits::Zero;
15use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
16use malachite_base::num::conversion::traits::ExactFrom;
17use malachite_base::rounding_modes::RoundingMode;
18use malachite_nz::integer::Integer;
19use malachite_nz::natural::Natural;
20use malachite_nz::platform::{Limb, SignedLimb};
21
22const fn const_limb_significant_bits(x: Limb) -> u64 {
23    Limb::WIDTH - (x.leading_zeros() as u64)
24}
25
26impl Float {
27    /// Converts an unsigned primitive integer to a [`Float`], after multiplying it by the specified
28    /// power of 2.
29    ///
30    /// The type of the integer is `u64`, unless the `32_bit_limbs` feature is set, in which case
31    /// the type is `u32`.
32    ///
33    /// If the integer is nonzero, the precision of the [`Float`] is the minimum possible precision
34    /// to represent the integer exactly.
35    ///
36    /// If you don't need to use this function in a const context, try just using `from` instead,
37    /// followed by `>>` or `<<`.
38    ///
39    /// $$
40    /// f(x,k) = x2^k.
41    /// $$
42    ///
43    /// # Worst-case complexity
44    /// Constant time and additional memory.
45    ///
46    /// # Panics
47    /// Panics if the result is too large or too small to be represented by a `Float`.
48    ///
49    /// # Examples
50    /// ```
51    /// use malachite_float::Float;
52    ///
53    /// assert_eq!(
54    ///     Float::const_from_unsigned_times_power_of_2(0, 0).to_string(),
55    ///     "0.0"
56    /// );
57    /// assert_eq!(
58    ///     Float::const_from_unsigned_times_power_of_2(123, 0).to_string(),
59    ///     "123.0"
60    /// );
61    /// assert_eq!(
62    ///     Float::const_from_unsigned_times_power_of_2(123, 1).to_string(),
63    ///     "246.0"
64    /// );
65    /// assert_eq!(
66    ///     Float::const_from_unsigned_times_power_of_2(123, -1).to_string(),
67    ///     "61.5"
68    /// );
69    /// #[cfg(not(feature = "32_bit_limbs"))]
70    /// {
71    ///     assert_eq!(
72    ///         Float::const_from_unsigned_times_power_of_2(884279719003555, -48).to_string(),
73    ///         "3.141592653589793"
74    ///     );
75    /// }
76    /// ```
77    pub const fn const_from_unsigned_times_power_of_2(x: Limb, pow: i32) -> Self {
78        if x == 0 {
79            return Self::ZERO;
80        }
81        let bits = const_limb_significant_bits(x);
82        let exponent = (bits as i32).saturating_add(pow);
83        assert!(exponent <= Self::MAX_EXPONENT);
84        assert!(exponent >= Self::MIN_EXPONENT);
85        let prec = bits - x.trailing_zeros() as u64;
86        Self(Finite {
87            sign: true,
88            exponent,
89            precision: prec,
90            significand: Natural::const_from(x << (Limb::WIDTH - bits)),
91        })
92    }
93
94    /// Converts an unsigned primitive integer to a [`Float`].
95    ///
96    /// The type of the integer is `u64`, unless the `32_bit_limbs` feature is set, in which case
97    /// the type is `u32`.
98    ///
99    /// If the integer is nonzero, the precision of the [`Float`] is the minimum possible precision
100    /// to represent the integer exactly.
101    ///
102    /// If you don't need to use this function in a const context, try just using `from` instead; it
103    /// will probably be slightly faster.
104    ///
105    /// This function does not overflow or underflow.
106    ///
107    /// # Worst-case complexity
108    /// Constant time and additional memory.
109    ///
110    /// # Examples
111    /// ```
112    /// use malachite_float::Float;
113    ///
114    /// assert_eq!(Float::const_from_unsigned(0).to_string(), "0.0");
115    /// assert_eq!(Float::const_from_unsigned(123).to_string(), "123.0");
116    /// ```
117    #[inline]
118    pub const fn const_from_unsigned(x: Limb) -> Self {
119        Self::const_from_unsigned_times_power_of_2(x, 0)
120    }
121
122    /// Converts a signed primitive integer to a [`Float`], after multiplying it by the specified
123    /// power of 2.
124    ///
125    /// The type of the integer is `i64`, unless the `32_bit_limbs` feature is set, in which case
126    /// the type is `i32`.
127    ///
128    /// If the integer is nonzero, the precision of the [`Float`] is the minimum possible precision
129    /// to represent the integer exactly.
130    ///
131    /// If you don't need to use this function in a const context, try just using `from` instead,
132    /// followed by `>>` or `<<`.
133    ///
134    /// $$
135    /// f(x,k) = x2^k.
136    /// $$
137    ///
138    /// # Worst-case complexity
139    /// Constant time and additional memory.
140    ///
141    /// # Panics
142    /// Panics if the result is too large or too small to be represented by a `Float`.
143    ///
144    /// # Examples
145    /// ```
146    /// use malachite_float::Float;
147    ///
148    /// assert_eq!(
149    ///     Float::const_from_signed_times_power_of_2(0, 0).to_string(),
150    ///     "0.0"
151    /// );
152    /// assert_eq!(
153    ///     Float::const_from_signed_times_power_of_2(123, 0).to_string(),
154    ///     "123.0"
155    /// );
156    /// assert_eq!(
157    ///     Float::const_from_signed_times_power_of_2(123, 1).to_string(),
158    ///     "246.0"
159    /// );
160    /// assert_eq!(
161    ///     Float::const_from_signed_times_power_of_2(123, -1).to_string(),
162    ///     "61.5"
163    /// );
164    /// assert_eq!(
165    ///     Float::const_from_signed_times_power_of_2(-123, 0).to_string(),
166    ///     "-123.0"
167    /// );
168    /// assert_eq!(
169    ///     Float::const_from_signed_times_power_of_2(-123, 1).to_string(),
170    ///     "-246.0"
171    /// );
172    /// assert_eq!(
173    ///     Float::const_from_signed_times_power_of_2(-123, -1).to_string(),
174    ///     "-61.5"
175    /// );
176    /// #[cfg(not(feature = "32_bit_limbs"))]
177    /// {
178    ///     assert_eq!(
179    ///         Float::const_from_signed_times_power_of_2(884279719003555, -48).to_string(),
180    ///         "3.141592653589793"
181    ///     );
182    ///     assert_eq!(
183    ///         Float::const_from_signed_times_power_of_2(-884279719003555, -48).to_string(),
184    ///         "-3.141592653589793"
185    ///     );
186    /// }
187    /// ```
188    pub const fn const_from_signed_times_power_of_2(x: SignedLimb, pow: i32) -> Self {
189        if x == 0 {
190            return Self::ZERO;
191        }
192        let x_abs = x.unsigned_abs();
193        let bits = const_limb_significant_bits(x_abs);
194        let exponent = (bits as i32).saturating_add(pow);
195        assert!(exponent <= Self::MAX_EXPONENT);
196        assert!(exponent >= Self::MIN_EXPONENT);
197        let prec = bits - x_abs.trailing_zeros() as u64;
198        Self(Finite {
199            sign: x > 0,
200            exponent,
201            precision: prec,
202            significand: Natural::const_from(x_abs << (Limb::WIDTH - bits)),
203        })
204    }
205
206    /// Converts a signed primitive integer to a [`Float`].
207    ///
208    /// The type of the integer is `i64`, unless the `32_bit_limbs` feature is set, in which case
209    /// the type is `i32`.
210    ///
211    /// If the integer is nonzero, the precision of the [`Float`] is the minimum possible precision
212    /// to represent the integer exactly.
213    ///
214    /// If you don't need to use this function in a const context, try just using `from` instead; it
215    /// will probably be slightly faster.
216    ///
217    /// This function does not overflow or underflow.
218    ///
219    /// # Worst-case complexity
220    /// Constant time and additional memory.
221    ///
222    /// # Examples
223    /// ```
224    /// use malachite_float::Float;
225    ///
226    /// assert_eq!(Float::const_from_signed(0).to_string(), "0.0");
227    /// assert_eq!(Float::const_from_signed(123).to_string(), "123.0");
228    /// assert_eq!(Float::const_from_signed(-123).to_string(), "-123.0");
229    /// ```
230    #[inline]
231    pub const fn const_from_signed(x: SignedLimb) -> Self {
232        Self::const_from_signed_times_power_of_2(x, 0)
233    }
234
235    /// Converts a primitive unsigned integer to a [`Float`]. If the [`Float`] is nonzero, it has
236    /// the specified precision. If rounding is needed, the specified rounding mode is used. An
237    /// [`Ordering`] is also returned, indicating whether the returned value is less than, equal to,
238    /// or greater than the original value.
239    ///
240    /// If you're only using `Nearest`, try using [`Float::from_unsigned_prec`] instead.
241    ///
242    /// This function does not overflow or underflow.
243    ///
244    /// # Worst-case complexity
245    /// $T(n) = O(n)$
246    ///
247    /// $M(n) = O(n)$
248    ///
249    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
250    ///
251    /// # Panics
252    /// Panics if `prec` is zero, or if `rm` is exact and the primitive integer cannot be exactly
253    /// represented with the specified precision.
254    ///
255    /// # Examples
256    /// See [here](super::from_primitive_int#from_unsigned_prec_round).
257    #[inline]
258    pub fn from_unsigned_prec_round<T: PrimitiveUnsigned>(
259        x: T,
260        prec: u64,
261        rm: RoundingMode,
262    ) -> (Self, Ordering)
263    where
264        Natural: From<T>,
265    {
266        Self::from_natural_prec_round(Natural::from(x), prec, rm)
267    }
268
269    /// Converts an unsigned primitive integer to a [`Float`]. If the [`Float`] is nonzero, it has
270    /// the specified precision. An [`Ordering`] is also returned, indicating whether the returned
271    /// value is less than, equal to, or greater than the original value.
272    ///
273    /// If you want the [`Float`]'s precision to be equal to the integer's number of significant
274    /// bits, try just using `Float::from` instead.
275    ///
276    /// Rounding may occur, in which case `Nearest` is used by default. To specify a rounding mode
277    /// as well as a precision, try [`Float::from_unsigned_prec_round`].
278    ///
279    /// This function does not overflow or underflow.
280    ///
281    /// # Worst-case complexity
282    /// $T(n) = O(n)$
283    ///
284    /// $M(n) = O(n)$
285    ///
286    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
287    ///
288    /// # Panics
289    /// Panics if `prec` is zero.
290    ///
291    /// # Examples
292    /// See [here](super::from_primitive_int#from_unsigned_prec).
293    #[inline]
294    pub fn from_unsigned_prec<T: PrimitiveUnsigned>(x: T, prec: u64) -> (Self, Ordering)
295    where
296        Natural: From<T>,
297    {
298        Self::from_natural_prec(Natural::from(x), prec)
299    }
300
301    /// Converts a primitive signed integer to a [`Float`]. If the [`Float`] is nonzero, it has the
302    /// specified precision. If rounding is needed, the specified rounding mode is used. An
303    /// [`Ordering`] is also returned, indicating whether the returned value is less than, equal to,
304    /// or greater than the original value.
305    ///
306    /// If you're only using `Nearest`, try using [`Float::from_signed_prec`] instead.
307    ///
308    /// This function does not overflow or underflow.
309    ///
310    /// # Worst-case complexity
311    /// $T(n) = O(n)$
312    ///
313    /// $M(n) = O(n)$
314    ///
315    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
316    ///
317    /// # Panics
318    /// Panics if `prec` is zero, or if `rm` is exact and the primitive integer cannot be exactly
319    /// represented with the specified precision.
320    ///
321    /// # Examples
322    /// See [here](super::from_primitive_int#from_signed_prec_round).
323    #[inline]
324    pub fn from_signed_prec_round<T: PrimitiveSigned>(
325        x: T,
326        prec: u64,
327        rm: RoundingMode,
328    ) -> (Self, Ordering)
329    where
330        Integer: From<T>,
331    {
332        Self::from_integer_prec_round(Integer::from(x), prec, rm)
333    }
334
335    /// Converts a signed primitive integer to a [`Float`]. If the [`Float`] is nonzero, it has the
336    /// specified precision. An [`Ordering`] is also returned, indicating whether the returned value
337    /// is less than, equal to, or greater than the original value.
338    ///
339    /// If you want the [`Float`]'s precision to be equal to the integer's number of significant
340    /// bits, try just using `Float::from` instead.
341    ///
342    /// Rounding may occur, in which case `Nearest` is used by default. To specify a rounding mode
343    /// as well as a precision, try [`Float::from_signed_prec_round`].
344    ///
345    /// This function does not overflow or underflow.
346    ///
347    /// # Worst-case complexity
348    /// $T(n) = O(n)$
349    ///
350    /// $M(n) = O(n)$
351    ///
352    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
353    ///
354    /// # Panics
355    /// Panics if `prec` is zero.
356    ///
357    /// # Examples
358    /// See [here](super::from_primitive_int#from_signed_prec).
359    #[inline]
360    pub fn from_signed_prec<T: PrimitiveSigned>(x: T, prec: u64) -> (Self, Ordering)
361    where
362        Integer: From<T>,
363    {
364        Self::from_integer_prec(Integer::from(x), prec)
365    }
366}
367
368macro_rules! impl_from_unsigned {
369    ($t: ident) => {
370        impl From<$t> for Float {
371            /// Converts an unsigned primitive integer to a [`Float`].
372            ///
373            /// If the integer is nonzero, the precision of the [`Float`] is equal to the integer's
374            /// number of significant bits. If you want to specify a different precision, try
375            /// [`Float::from_unsigned_prec`]. This may require rounding, which uses `Nearest` by
376            /// default. To specify a rounding mode as well as a precision, try
377            /// [`Float::from_unsigned_prec_round`].
378            ///
379            /// If you want to create a [`Float`] from an unsigned primitive integer in a const
380            /// context, try [`Float::const_from_unsigned`] instead.
381            ///
382            /// This function does not overflow or underflow.
383            ///
384            /// # Worst-case complexity
385            /// Constant time and additional memory.
386            ///
387            /// # Examples
388            /// See [here](super::from_primitive_int#from).
389            #[inline]
390            fn from(u: $t) -> Float {
391                Float::exact_from(Natural::from(u))
392            }
393        }
394    };
395}
396apply_to_unsigneds!(impl_from_unsigned);
397
398macro_rules! impl_from_signed {
399    ($t: ident) => {
400        impl From<$t> for Float {
401            /// Converts a signed primitive integer to a [`Float`].
402            ///
403            /// If the integer is nonzero, the precision of the [`Float`] is equal to the integer's
404            /// number of significant bits. If you want to specify a different precision, try
405            /// [`Float::from_signed_prec`]. This may require rounding, which uses `Nearest` by
406            /// default. To specify a rounding mode as well as a precision, try
407            /// [`Float::from_signed_prec_round`].
408            ///
409            /// If you want to create a [`Float`] from an signed primitive integer in a const
410            /// context, try [`Float::const_from_signed`] instead.
411            ///
412            /// This function does not overflow or underflow.
413            ///
414            /// # Worst-case complexity
415            /// Constant time and additional memory.
416            ///
417            /// # Examples
418            /// See [here](super::from_primitive_int#from).
419            #[inline]
420            fn from(i: $t) -> Float {
421                Float::exact_from(Integer::from(i))
422            }
423        }
424    };
425}
426apply_to_signeds!(impl_from_signed);