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