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::Float;
10use crate::conversion::from_natural::{
11 from_natural_prec_round_zero_exponent, from_natural_zero_exponent,
12};
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 { f } else { -f }
24}
25
26pub(crate) fn from_integer_prec_round_zero_exponent(
27 x: Integer,
28 prec: u64,
29 rm: RoundingMode,
30) -> (Float, Ordering) {
31 let sign = x >= 0;
32 let (f, o) =
33 from_natural_prec_round_zero_exponent(x.unsigned_abs(), prec, if sign { rm } else { -rm });
34 if sign { (f, o) } else { (-f, o.reverse()) }
35}
36
37impl Float {
38 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value. If the [`Float`] is
39 /// nonzero, it has the specified precision. If rounding is needed, the specified rounding mode
40 /// is used. An [`Ordering`] is also returned, indicating whether the returned value is less
41 /// than, equal to, or greater than the original value.
42 ///
43 /// If you're only using [`Nearest`], try using [`Float::from_integer_prec`] instead.
44 ///
45 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
46 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
47 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
48 /// - If the [`Integer`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this function
49 /// overflows to $-\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds up to
50 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
51 ///
52 /// # Worst-case complexity
53 /// $T(m,n) = O(\max(m,n))$
54 ///
55 /// $M(n) = O(n)$
56 ///
57 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
58 /// `prec`.
59 ///
60 /// # Panics
61 /// Panics if `prec` is zero, or if `rm` is exact and the `Integer` cannot be exactly
62 /// represented with the specified precision.
63 ///
64 /// # Examples
65 /// ```
66 /// use malachite_base::num::basic::traits::Zero;
67 /// use malachite_base::rounding_modes::RoundingMode::*;
68 /// use malachite_float::Float;
69 /// use malachite_nz::integer::Integer;
70 /// use std::cmp::Ordering::*;
71 ///
72 /// let (x, o) = Float::from_integer_prec_round(Integer::ZERO, 10, Exact);
73 /// assert_eq!(x.to_string(), "0.0");
74 /// assert_eq!(o, Equal);
75 ///
76 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 20, Exact);
77 /// assert_eq!(x.to_string(), "123.0");
78 /// assert_eq!(x.get_prec(), Some(20));
79 /// assert_eq!(o, Equal);
80 ///
81 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 4, Floor);
82 /// assert_eq!(x.to_string(), "1.2e2");
83 /// assert_eq!(x.get_prec(), Some(4));
84 /// assert_eq!(o, Less);
85 ///
86 /// let (x, o) = Float::from_integer_prec_round(Integer::from(123), 4, Ceiling);
87 /// assert_eq!(x.to_string(), "1.3e2");
88 /// assert_eq!(x.get_prec(), Some(4));
89 /// assert_eq!(o, Greater);
90 ///
91 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 20, Exact);
92 /// assert_eq!(x.to_string(), "-123.0");
93 /// assert_eq!(x.get_prec(), Some(20));
94 /// assert_eq!(o, Equal);
95 ///
96 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 4, Floor);
97 /// assert_eq!(x.to_string(), "-1.3e2");
98 /// assert_eq!(x.get_prec(), Some(4));
99 /// assert_eq!(o, Less);
100 ///
101 /// let (x, o) = Float::from_integer_prec_round(Integer::from(-123), 4, Ceiling);
102 /// assert_eq!(x.to_string(), "-1.2e2");
103 /// assert_eq!(x.get_prec(), Some(4));
104 /// assert_eq!(o, Greater);
105 /// ```
106 #[inline]
107 pub fn from_integer_prec_round(x: Integer, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
108 let sign = x >= 0;
109 let (f, o) =
110 Self::from_natural_prec_round(x.unsigned_abs(), prec, if sign { rm } else { -rm });
111 if sign { (f, o) } else { (-f, o.reverse()) }
112 }
113
114 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference. If the
115 /// [`Float`] is nonzero, it has the specified precision. If rounding is needed, the specified
116 /// rounding mode is used. An [`Ordering`] is also returned, indicating whether the returned
117 /// value is less than, equal to, or greater than the original value.
118 ///
119 /// If you're only using [`Nearest`], try using [`Float::from_integer_prec_ref`] instead.
120 ///
121 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
122 /// function overflows to $\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds down
123 /// to $(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
124 /// - If the [`Integer`] rounds to a value less than or equal to $-2^{2^{30}-1}$), this function
125 /// overflows to $-\infty$ if `rm` is `Ceiling`, `Up`, or `Nearest`, and rounds up to
126 /// $-(1-(1/2)^p)2^{2^{30}-1}$ otherwise, where $p$ is `prec`.
127 ///
128 /// # Worst-case complexity
129 /// $T(m,n) = O(\max(m,n))$
130 ///
131 /// $M(n) = O(n)$
132 ///
133 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
134 /// `prec`.
135 ///
136 /// # Panics
137 /// Panics if `prec` is zero, or if `rm` is exact and the `Integer` cannot be exactly
138 /// represented with the specified precision.
139 ///
140 /// # Examples
141 /// ```
142 /// use malachite_base::num::basic::traits::Zero;
143 /// use malachite_base::rounding_modes::RoundingMode::*;
144 /// use malachite_float::Float;
145 /// use malachite_nz::integer::Integer;
146 /// use std::cmp::Ordering::*;
147 ///
148 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::ZERO, 10, Exact);
149 /// assert_eq!(x.to_string(), "0.0");
150 /// assert_eq!(o, Equal);
151 ///
152 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 20, Exact);
153 /// assert_eq!(x.to_string(), "123.0");
154 /// assert_eq!(x.get_prec(), Some(20));
155 /// assert_eq!(o, Equal);
156 ///
157 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 4, Floor);
158 /// assert_eq!(x.to_string(), "1.2e2");
159 /// assert_eq!(x.get_prec(), Some(4));
160 /// assert_eq!(o, Less);
161 ///
162 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(123), 4, Ceiling);
163 /// assert_eq!(x.to_string(), "1.3e2");
164 /// assert_eq!(x.get_prec(), Some(4));
165 /// assert_eq!(o, Greater);
166 ///
167 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 20, Exact);
168 /// assert_eq!(x.to_string(), "-123.0");
169 /// assert_eq!(x.get_prec(), Some(20));
170 /// assert_eq!(o, Equal);
171 ///
172 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 4, Floor);
173 /// assert_eq!(x.to_string(), "-1.3e2");
174 /// assert_eq!(x.get_prec(), Some(4));
175 /// assert_eq!(o, Less);
176 ///
177 /// let (x, o) = Float::from_integer_prec_round_ref(&Integer::from(-123), 4, Ceiling);
178 /// assert_eq!(x.to_string(), "-1.2e2");
179 /// assert_eq!(x.get_prec(), Some(4));
180 /// assert_eq!(o, Greater);
181 /// ```
182 #[inline]
183 pub fn from_integer_prec_round_ref(
184 x: &Integer,
185 prec: u64,
186 rm: RoundingMode,
187 ) -> (Self, Ordering) {
188 let sign = *x >= 0;
189 let (f, o) = Self::from_natural_prec_round_ref(
190 x.unsigned_abs_ref(),
191 prec,
192 if sign { rm } else { -rm },
193 );
194 if sign { (f, o) } else { (-f, o.reverse()) }
195 }
196
197 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value. If the [`Float`] is
198 /// nonzero, it has the specified precision. An [`Ordering`] is also returned, indicating
199 /// whether the returned value is less than, equal to, or greater than the original value.
200 ///
201 /// If you want the [`Float`]'s precision to be equal to the [`Integer`]'s number of significant
202 /// bits, try just using `Float::try_from` instead.
203 ///
204 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
205 /// as well as a precision, try [`Float::from_integer_prec_round`].
206 ///
207 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
208 /// function overflows to $\infty$.
209 /// - If the [`Integer`] rounds to a value less than or equal to -$2^{2^{30}-1}$), this function
210 /// overflows to $\infty$.
211 ///
212 /// # Worst-case complexity
213 /// $T(m,n) = O(\max(m,n))$
214 ///
215 /// $M(n) = O(n)$
216 ///
217 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
218 /// `prec`.
219 ///
220 /// # Panics
221 /// Panics if `prec` is zero.
222 ///
223 /// # Examples
224 /// ```
225 /// use malachite_base::num::basic::traits::Zero;
226 /// use malachite_float::Float;
227 /// use malachite_nz::integer::Integer;
228 /// use std::cmp::Ordering::*;
229 ///
230 /// let (x, o) = Float::from_integer_prec(Integer::ZERO, 10);
231 /// assert_eq!(x.to_string(), "0.0");
232 /// assert_eq!(o, Equal);
233 ///
234 /// let (x, o) = Float::from_integer_prec(Integer::from(123), 20);
235 /// assert_eq!(x.to_string(), "123.0");
236 /// assert_eq!(x.get_prec(), Some(20));
237 /// assert_eq!(o, Equal);
238 ///
239 /// let (x, o) = Float::from_integer_prec(Integer::from(123), 4);
240 /// assert_eq!(x.to_string(), "1.2e2");
241 /// assert_eq!(x.get_prec(), Some(4));
242 /// assert_eq!(o, Less);
243 ///
244 /// let (x, o) = Float::from_integer_prec(Integer::from(-123), 20);
245 /// assert_eq!(x.to_string(), "-123.0");
246 /// assert_eq!(x.get_prec(), Some(20));
247 /// assert_eq!(o, Equal);
248 ///
249 /// let (x, o) = Float::from_integer_prec(Integer::from(-123), 4);
250 /// assert_eq!(x.to_string(), "-1.2e2");
251 /// assert_eq!(x.get_prec(), Some(4));
252 /// assert_eq!(o, Greater);
253 /// ```
254 #[inline]
255 pub fn from_integer_prec(x: Integer, prec: u64) -> (Self, Ordering) {
256 Self::from_integer_prec_round(x, prec, Nearest)
257 }
258
259 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference. If the
260 /// [`Float`] is nonzero, it has the specified precision. An [`Ordering`] is also returned,
261 /// indicating whether the returned value is less than, equal to, or greater than the original
262 /// value.
263 ///
264 /// If you want the [`Float`]'s precision to be equal to the [`Integer`]'s number of significant
265 /// bits, try just using `Float::try_from` instead.
266 ///
267 /// Rounding may occur, in which case [`Nearest`] is used by default. To specify a rounding mode
268 /// as well as a precision, try [`Float::from_integer_prec_round_ref`].
269 ///
270 /// - If the [`Integer`] rounds to a value greater than or equal to $2^{2^{30}-1}$), this
271 /// function overflows to $\infty$.
272 /// - If the [`Integer`] rounds to a value less than or equal to -$2^{2^{30}-1}$), this function
273 /// overflows to $\infty$.
274 ///
275 /// # Worst-case complexity
276 /// $T(m,n) = O(\max(m,n))$
277 ///
278 /// $M(n) = O(n)$
279 ///
280 /// where $T$ is time, $M$ is additional memory, $m$ is `n.significant_bits()`, and $n$ is
281 /// `prec`.
282 ///
283 /// # Panics
284 /// Panics if `prec` is zero.
285 ///
286 /// # Examples
287 /// ```
288 /// use malachite_base::num::basic::traits::Zero;
289 /// use malachite_float::Float;
290 /// use malachite_nz::integer::Integer;
291 /// use std::cmp::Ordering::*;
292 ///
293 /// let (x, o) = Float::from_integer_prec_ref(&Integer::ZERO, 10);
294 /// assert_eq!(x.to_string(), "0.0");
295 /// assert_eq!(o, Equal);
296 ///
297 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(123), 20);
298 /// assert_eq!(x.to_string(), "123.0");
299 /// assert_eq!(x.get_prec(), Some(20));
300 /// assert_eq!(o, Equal);
301 ///
302 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(123), 4);
303 /// assert_eq!(x.to_string(), "1.2e2");
304 /// assert_eq!(x.get_prec(), Some(4));
305 /// assert_eq!(o, Less);
306 ///
307 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(-123), 20);
308 /// assert_eq!(x.to_string(), "-123.0");
309 /// assert_eq!(x.get_prec(), Some(20));
310 /// assert_eq!(o, Equal);
311 ///
312 /// let (x, o) = Float::from_integer_prec_ref(&Integer::from(-123), 4);
313 /// assert_eq!(x.to_string(), "-1.2e2");
314 /// assert_eq!(x.get_prec(), Some(4));
315 /// assert_eq!(o, Greater);
316 /// ```
317 #[inline]
318 pub fn from_integer_prec_ref(x: &Integer, prec: u64) -> (Self, Ordering) {
319 let sign = *x >= 0;
320 let (f, o) = Self::from_natural_prec_ref(x.unsigned_abs_ref(), prec);
321 if sign { (f, o) } else { (-f, o.reverse()) }
322 }
323}
324
325impl TryFrom<Integer> for Float {
326 type Error = FloatConversionError;
327
328 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by value.
329 ///
330 /// If the [`Integer`] is nonzero, the precision of the [`Float`] is the minimum possible
331 /// precision to represent the [`Integer`] exactly. If you want to specify some other precision,
332 /// try [`Float::from_integer_prec`]. This may require rounding, which uses [`Nearest`] by
333 /// default. To specify a rounding mode as well as a precision, try
334 /// [`Float::from_integer_prec_round`].
335 ///
336 /// If the absolue value of the [`Integer`] is greater than or equal to $2^{2^{30}-1}$, this
337 /// function returns an overflow error.
338 ///
339 /// # Worst-case complexity
340 /// $T(n) = O(n)$
341 ///
342 /// $M(n) = O(1)$
343 ///
344 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
345 ///
346 /// # Examples
347 /// ```
348 /// use malachite_base::num::basic::traits::Zero;
349 /// use malachite_float::Float;
350 /// use malachite_nz::integer::Integer;
351 ///
352 /// assert_eq!(Float::try_from(Integer::ZERO).unwrap().to_string(), "0.0");
353 /// assert_eq!(
354 /// Float::try_from(Integer::from(123)).unwrap().to_string(),
355 /// "123.0"
356 /// );
357 /// assert_eq!(
358 /// Float::try_from(Integer::from(123)).unwrap().get_prec(),
359 /// Some(7)
360 /// );
361 /// assert_eq!(
362 /// Float::try_from(Integer::from(10)).unwrap().to_string(),
363 /// "10.0"
364 /// );
365 /// assert_eq!(
366 /// Float::try_from(Integer::from(10)).unwrap().get_prec(),
367 /// Some(3)
368 /// );
369 /// assert_eq!(
370 /// Float::try_from(Integer::from(-123)).unwrap().to_string(),
371 /// "-123.0"
372 /// );
373 /// assert_eq!(
374 /// Float::try_from(Integer::from(-123)).unwrap().get_prec(),
375 /// Some(7)
376 /// );
377 /// assert_eq!(
378 /// Float::try_from(Integer::from(-10)).unwrap().to_string(),
379 /// "-10.0"
380 /// );
381 /// assert_eq!(
382 /// Float::try_from(Integer::from(-10)).unwrap().get_prec(),
383 /// Some(3)
384 /// );
385 /// ```
386 #[inline]
387 fn try_from(n: Integer) -> Result<Self, Self::Error> {
388 let sign = n >= 0;
389 let abs = Self::try_from(n.unsigned_abs())?;
390 Ok(if sign { abs } else { -abs })
391 }
392}
393
394impl TryFrom<&Integer> for Float {
395 type Error = FloatConversionError;
396
397 /// Converts an [`Integer`] to a [`Float`], taking the [`Integer`] by reference.
398 ///
399 /// If the [`Integer`] is nonzero, the precision of the [`Float`] is the minimum possible
400 /// precision to represent the [`Integer`] exactly. If you want to specify some other precision,
401 /// try [`Float::from_integer_prec`]. This may require rounding, which uses [`Nearest`] by
402 /// default. To specify a rounding mode as well as a precision, try
403 /// [`Float::from_integer_prec_round`].
404 ///
405 /// If the absolue value of the [`Integer`] is greater than or equal to $2^{2^{30}-1}$, this
406 /// function returns an overflow error.
407 ///
408 /// # Worst-case complexity
409 /// $T(n) = O(n)$
410 ///
411 /// $M(n) = O(1)$
412 ///
413 /// where $T$ is time, $M$ is additional memory, and $n$ is `n.significant_bits()`.
414 ///
415 /// # Examples
416 /// ```
417 /// use malachite_base::num::basic::traits::Zero;
418 /// use malachite_float::Float;
419 /// use malachite_nz::integer::Integer;
420 ///
421 /// assert_eq!(Float::try_from(&Integer::ZERO).unwrap().to_string(), "0.0");
422 /// assert_eq!(
423 /// Float::try_from(&Integer::from(123)).unwrap().to_string(),
424 /// "123.0"
425 /// );
426 /// assert_eq!(
427 /// Float::try_from(&Integer::from(123)).unwrap().get_prec(),
428 /// Some(7)
429 /// );
430 /// assert_eq!(
431 /// Float::try_from(&Integer::from(10)).unwrap().to_string(),
432 /// "10.0"
433 /// );
434 /// assert_eq!(
435 /// Float::try_from(&Integer::from(10)).unwrap().get_prec(),
436 /// Some(3)
437 /// );
438 /// assert_eq!(
439 /// Float::try_from(&Integer::from(-123)).unwrap().to_string(),
440 /// "-123.0"
441 /// );
442 /// assert_eq!(
443 /// Float::try_from(&Integer::from(-123)).unwrap().get_prec(),
444 /// Some(7)
445 /// );
446 /// assert_eq!(
447 /// Float::try_from(&Integer::from(-10)).unwrap().to_string(),
448 /// "-10.0"
449 /// );
450 /// assert_eq!(
451 /// Float::try_from(&Integer::from(-10)).unwrap().get_prec(),
452 /// Some(3)
453 /// );
454 /// ```
455 #[inline]
456 fn try_from(n: &Integer) -> Result<Self, Self::Error> {
457 let sign = *n >= 0;
458 let abs = Self::try_from(n.unsigned_abs())?;
459 Ok(if sign { abs } else { -abs })
460 }
461}
462
463impl ConvertibleFrom<&Integer> for Float {
464 /// Determines whether an [`Integer`] can be converted to an [`Float`], taking the [`Integer`]
465 /// by reference.
466 ///
467 /// The [`Integer`]s that are convertible to [`Float`]s are those whose that would not overflow:
468 /// that is, those whose absolute values are less than $2^{2^{30}-1}$.
469 ///
470 /// # Worst-case complexity
471 /// $T(n) = O(n)$
472 ///
473 /// $M(n) = O(1)$
474 ///
475 /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
476 ///
477 /// # Examples
478 /// ```
479 /// use malachite_base::num::basic::traits::Zero;
480 /// use malachite_base::num::conversion::traits::ConvertibleFrom;
481 /// use malachite_float::Float;
482 /// use malachite_nz::integer::Integer;
483 ///
484 /// assert_eq!(Float::convertible_from(&Integer::ZERO), true);
485 /// assert_eq!(Float::convertible_from(&Integer::from(3u8)), true);
486 /// ```
487 #[inline]
488 fn convertible_from(x: &Integer) -> bool {
489 *x == 0
490 || (Self::MIN_EXPONENT..=Self::MAX_EXPONENT).contains(
491 &i32::saturating_from(x.unsigned_abs_ref().floor_log_base_2()).saturating_add(1),
492 )
493 }
494}