malachite_nz/gaussian_integer/conversion/string/to_string.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::gaussian_integer::{
10 ComparableGaussianInteger, ComparableGaussianIntegerRef, GaussianInteger,
11};
12use core::fmt::{Debug, Display, Formatter, Result, Write};
13
14impl Display for GaussianInteger {
15 /// Converts a [`GaussianInteger`] to a [`String`].
16 ///
17 /// A value with a zero imaginary part is written as its real part alone; in particular, zero is
18 /// `"0"`. A purely imaginary value is written as a coefficient directly followed by `'i'`, with
19 /// coefficients of 1 and -1 elided, giving `"i"` and `"-i"`. Otherwise, the real term is
20 /// written first and the imaginary term follows with a joining sign, as in `"1+i"` and
21 /// `"2-3i"`.
22 ///
23 /// # Worst-case complexity
24 /// $T(n) = O(n (\log n)^2 \log\log n)$
25 ///
26 /// $M(n) = O(n \log n)$
27 ///
28 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
29 /// bits of the real and imaginary parts.
30 ///
31 /// # Examples
32 /// ```
33 /// use malachite_base::num::conversion::traits::ImaginaryFrom;
34 /// use malachite_nz::gaussian_integer::GaussianInteger;
35 /// use malachite_nz::integer::Integer;
36 ///
37 /// assert_eq!(GaussianInteger::default().to_string(), "0");
38 /// assert_eq!(GaussianInteger::from(2).to_string(), "2");
39 /// assert_eq!(GaussianInteger::from(-2).to_string(), "-2");
40 /// assert_eq!(GaussianInteger::imaginary_from(1).to_string(), "i");
41 /// assert_eq!(GaussianInteger::imaginary_from(-1).to_string(), "-i");
42 /// assert_eq!(GaussianInteger::imaginary_from(2).to_string(), "2i");
43 /// assert_eq!(GaussianInteger::imaginary_from(-2).to_string(), "-2i");
44 ///
45 /// let g = GaussianInteger {
46 /// real: Integer::from(1),
47 /// imaginary: Integer::from(1),
48 /// };
49 /// assert_eq!(g.to_string(), "1+i");
50 /// let g = GaussianInteger {
51 /// real: Integer::from(1),
52 /// imaginary: Integer::from(-1),
53 /// };
54 /// assert_eq!(g.to_string(), "1-i");
55 /// let g = GaussianInteger {
56 /// real: Integer::from(2),
57 /// imaginary: Integer::from(3),
58 /// };
59 /// assert_eq!(g.to_string(), "2+3i");
60 /// let g = GaussianInteger {
61 /// real: Integer::from(2),
62 /// imaginary: Integer::from(-3),
63 /// };
64 /// assert_eq!(g.to_string(), "2-3i");
65 /// ```
66 fn fmt(&self, f: &mut Formatter) -> Result {
67 if self.imaginary == 0u32 {
68 return Display::fmt(&self.real, f);
69 }
70 if self.real != 0u32 {
71 Display::fmt(&self.real, f)?;
72 if self.imaginary > 0u32 {
73 f.write_char('+')?;
74 }
75 }
76 if self.imaginary == 1u32 {
77 f.write_char('i')
78 } else if self.imaginary == -1i32 {
79 f.write_str("-i")
80 } else {
81 Display::fmt(&self.imaginary, f)?;
82 f.write_char('i')
83 }
84 }
85}
86
87impl Debug for GaussianInteger {
88 /// Converts a [`GaussianInteger`] to a [`String`].
89 ///
90 /// This is the same as the [`Display::fmt`] implementation, so that a collection of
91 /// [`GaussianInteger`]s is written the same way its elements are displayed.
92 ///
93 /// # Worst-case complexity
94 /// $T(n) = O(n (\log n)^2 \log\log n)$
95 ///
96 /// $M(n) = O(n \log n)$
97 ///
98 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
99 /// bits of the real and imaginary parts.
100 ///
101 /// # Examples
102 /// ```
103 /// use core::str::FromStr;
104 /// use malachite_base::strings::ToDebugString;
105 /// use malachite_nz::gaussian_integer::GaussianInteger;
106 ///
107 /// let xs = vec![
108 /// GaussianInteger::from_str("2-3i").unwrap(),
109 /// GaussianInteger::from_str("i").unwrap(),
110 /// GaussianInteger::from_str("-5").unwrap(),
111 /// ];
112 /// assert_eq!(xs[0].to_debug_string(), "2-3i");
113 /// assert_eq!(xs[1].to_debug_string(), "i");
114 /// assert_eq!(xs[2].to_debug_string(), "-5");
115 /// assert_eq!(xs.to_debug_string(), "[2-3i, i, -5]");
116 /// ```
117 #[inline]
118 fn fmt(&self, f: &mut Formatter) -> Result {
119 Display::fmt(self, f)
120 }
121}
122
123impl Display for ComparableGaussianInteger {
124 /// Converts a [`ComparableGaussianInteger`] to a [`String`], writing the wrapped
125 /// [`GaussianInteger`] exactly as its own [`Display`] implementation does.
126 ///
127 /// # Worst-case complexity
128 /// $T(n) = O(n (\log n)^2 \log\log n)$
129 ///
130 /// $M(n) = O(n \log n)$
131 ///
132 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
133 /// bits of the real and imaginary parts.
134 ///
135 /// # Examples
136 /// ```
137 /// use malachite_base::num::basic::traits::I;
138 /// use malachite_nz::gaussian_integer::{ComparableGaussianInteger, GaussianInteger};
139 ///
140 /// assert_eq!(
141 /// ComparableGaussianInteger(GaussianInteger::I).to_string(),
142 /// "i"
143 /// );
144 /// ```
145 #[inline]
146 fn fmt(&self, f: &mut Formatter) -> Result {
147 Display::fmt(&self.0, f)
148 }
149}
150
151impl Display for ComparableGaussianIntegerRef<'_> {
152 /// Converts a [`ComparableGaussianIntegerRef`] to a [`String`], writing the wrapped
153 /// [`GaussianInteger`] exactly as its own [`Display`] implementation does.
154 ///
155 /// # Worst-case complexity
156 /// $T(n) = O(n (\log n)^2 \log\log n)$
157 ///
158 /// $M(n) = O(n \log n)$
159 ///
160 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
161 /// bits of the real and imaginary parts.
162 ///
163 /// # Examples
164 /// ```
165 /// use malachite_base::num::basic::traits::I;
166 /// use malachite_nz::gaussian_integer::{ComparableGaussianIntegerRef, GaussianInteger};
167 ///
168 /// let x = GaussianInteger::I;
169 /// assert_eq!(ComparableGaussianIntegerRef(&x).to_string(), "i");
170 /// ```
171 #[inline]
172 fn fmt(&self, f: &mut Formatter) -> Result {
173 Display::fmt(self.0, f)
174 }
175}