Skip to main content

malachite_float/float/conversion/
gaussian_integer_from_float.rs

1// Copyright © 2026 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 malachite_base::num::conversion::traits::ConvertibleFrom;
11use malachite_nz::gaussian_integer::GaussianInteger;
12use malachite_nz::integer::Integer;
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15pub struct GaussianIntegerFromFloatError;
16
17impl TryFrom<Float> for GaussianInteger {
18    type Error = GaussianIntegerFromFloatError;
19
20    /// Converts a [`Float`] to a [`GaussianInteger`], producing a purely real value and taking the
21    /// [`Float`] by value. If the [`Float`] is NaN, infinite, or not an integer, an error is
22    /// returned.
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(n)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
30    ///
31    /// # Examples
32    /// ```
33    /// use malachite_base::num::basic::traits::{Infinity, NaN};
34    /// use malachite_float::Float;
35    /// use malachite_float::float::conversion::gaussian_integer_from_float::*;
36    /// use malachite_nz::gaussian_integer::GaussianInteger;
37    ///
38    /// let x = Float::from(123);
39    /// assert_eq!(GaussianInteger::try_from(x).unwrap().to_string(), "123");
40    ///
41    /// let x = Float::from(-123);
42    /// assert_eq!(GaussianInteger::try_from(x).unwrap().to_string(), "-123");
43    ///
44    /// assert_eq!(
45    ///     GaussianInteger::try_from(Float::from(1.5)),
46    ///     Err(GaussianIntegerFromFloatError)
47    /// );
48    /// assert_eq!(
49    ///     GaussianInteger::try_from(Float::NAN),
50    ///     Err(GaussianIntegerFromFloatError)
51    /// );
52    /// assert_eq!(
53    ///     GaussianInteger::try_from(Float::INFINITY),
54    ///     Err(GaussianIntegerFromFloatError)
55    /// );
56    /// ```
57    #[inline]
58    fn try_from(x: Float) -> Result<Self, Self::Error> {
59        Integer::try_from(x)
60            .map(Self::from)
61            .map_err(|_| GaussianIntegerFromFloatError)
62    }
63}
64
65impl TryFrom<&Float> for GaussianInteger {
66    type Error = GaussianIntegerFromFloatError;
67
68    /// Converts a [`Float`] to a [`GaussianInteger`], producing a purely real value and taking the
69    /// [`Float`] by reference. If the [`Float`] is NaN, infinite, or not an integer, an error is
70    /// returned.
71    ///
72    /// # Worst-case complexity
73    /// $T(n) = O(n)$
74    ///
75    /// $M(n) = O(n)$
76    ///
77    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
78    ///
79    /// # Examples
80    /// ```
81    /// use malachite_base::num::basic::traits::{Infinity, NaN};
82    /// use malachite_float::Float;
83    /// use malachite_float::float::conversion::gaussian_integer_from_float::*;
84    /// use malachite_nz::gaussian_integer::GaussianInteger;
85    ///
86    /// let x = Float::from(123);
87    /// assert_eq!(GaussianInteger::try_from(&x).unwrap().to_string(), "123");
88    ///
89    /// let x = Float::from(-123);
90    /// assert_eq!(GaussianInteger::try_from(&x).unwrap().to_string(), "-123");
91    ///
92    /// assert_eq!(
93    ///     GaussianInteger::try_from(&Float::from(1.5)),
94    ///     Err(GaussianIntegerFromFloatError)
95    /// );
96    /// assert_eq!(
97    ///     GaussianInteger::try_from(&Float::NAN),
98    ///     Err(GaussianIntegerFromFloatError)
99    /// );
100    /// assert_eq!(
101    ///     GaussianInteger::try_from(&Float::INFINITY),
102    ///     Err(GaussianIntegerFromFloatError)
103    /// );
104    /// ```
105    #[inline]
106    fn try_from(x: &Float) -> Result<Self, Self::Error> {
107        Integer::try_from(x)
108            .map(Self::from)
109            .map_err(|_| GaussianIntegerFromFloatError)
110    }
111}
112
113impl ConvertibleFrom<&Float> for GaussianInteger {
114    /// Determines whether a [`Float`] can be converted to a [`GaussianInteger`] (that is, whether
115    /// it is finite and an integer), taking the [`Float`] by reference.
116    ///
117    /// # Worst-case complexity
118    /// $T(n) = O(n)$
119    ///
120    /// $M(n) = O(1)$
121    ///
122    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
123    ///
124    /// # Examples
125    /// ```
126    /// use malachite_base::num::basic::traits::{Infinity, NaN};
127    /// use malachite_base::num::conversion::traits::ConvertibleFrom;
128    /// use malachite_float::Float;
129    /// use malachite_nz::gaussian_integer::GaussianInteger;
130    ///
131    /// assert_eq!(GaussianInteger::convertible_from(&Float::from(123)), true);
132    /// assert_eq!(GaussianInteger::convertible_from(&Float::from(-123)), true);
133    /// assert_eq!(GaussianInteger::convertible_from(&Float::from(1.5)), false);
134    /// assert_eq!(GaussianInteger::convertible_from(&Float::NAN), false);
135    /// assert_eq!(GaussianInteger::convertible_from(&Float::INFINITY), false);
136    /// ```
137    #[inline]
138    fn convertible_from(x: &Float) -> bool {
139        Integer::convertible_from(x)
140    }
141}