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