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);