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