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