malachite_float/float/conversion/string/latex.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::{ComparableFloat, ComparableFloatRef, Float};
10use alloc::string::ToString;
11use core::fmt::{Formatter, Result, Write};
12use malachite_base::strings::latex::ToLatex;
13
14impl ToLatex for Float {
15 /// Writes a [`Float`] as a LaTeX math-mode fragment.
16 ///
17 /// This is as the primitive floats are written. A NaN becomes `\text{NaN}` and the infinities
18 /// become `\infty` and `-\infty`. A finite [`Float`] is written as
19 /// [`Display`](core::fmt::Display) writes it, with the exponent, if there is one, lifted into a
20 /// real power of ten: `1.3e30` becomes ``1.3 \times 10^{30}``.
21 ///
22 /// As with [`Display`](core::fmt::Display), the digit count is determined by the [`Float`]'s
23 /// precision rather than by its value, and the two zeros are kept apart.
24 ///
25 /// # Worst-case complexity
26 /// $T(n) = O(n (\log n)^2 \log\log n)$
27 ///
28 /// $M(n) = O(n \log n)$
29 ///
30 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
31 ///
32 /// # Examples
33 /// ```
34 /// use malachite_base::num::arithmetic::traits::PowerOf2;
35 /// use malachite_base::num::basic::traits::{
36 /// Infinity, NaN, NegativeInfinity, NegativeZero, One, Zero,
37 /// };
38 /// use malachite_base::strings::latex::ToLatex;
39 /// use malachite_float::Float;
40 ///
41 /// assert_eq!(Float::NAN.to_latex_string(), r"\text{NaN}");
42 /// assert_eq!(Float::INFINITY.to_latex_string(), r"\infty");
43 /// assert_eq!(Float::NEGATIVE_INFINITY.to_latex_string(), r"-\infty");
44 /// assert_eq!(Float::ZERO.to_latex_string(), "0.0");
45 /// assert_eq!(Float::NEGATIVE_ZERO.to_latex_string(), "-0.0");
46 /// assert_eq!(Float::ONE.to_latex_string(), "1.0");
47 /// assert_eq!(Float::from(1.5).to_latex_string(), "1.5");
48 /// assert_eq!(
49 /// Float::power_of_2(100u64).to_latex_string(),
50 /// r"1.3 \times 10^{30}"
51 /// );
52 /// assert_eq!(
53 /// Float::power_of_2(-100i64).to_latex_string(),
54 /// r"7.9 \times 10^{-31}"
55 /// );
56 /// ```
57 ///
58 /// | value | fragment | renders as |
59 /// |-----------------------------|----------------------|----------------------|
60 /// | `Float::NAN` | `\text{NaN}` | $\text{NaN}$ |
61 /// | `Float::INFINITY` | `\infty` | $\infty$ |
62 /// | `Float::ONE` | `1.0` | $1.0$ |
63 /// | `Float::power_of_2(100u64)` | `1.3 \times 10^{30}` | $1.3 \times 10^{30}$ |
64 fn fmt_latex(&self, f: &mut Formatter) -> Result {
65 if self.is_nan() {
66 return f.write_str("\\text{NaN}");
67 } else if self.is_infinite() {
68 return f.write_str(if self.is_sign_positive() {
69 "\\infty"
70 } else {
71 "-\\infty"
72 });
73 }
74 let s = self.to_string();
75 let Some(e_index) = s.find('e') else {
76 return f.write_str(&s);
77 };
78 let (mantissa, exponent) = s.split_at(e_index);
79 let exponent = &exponent[1..];
80 f.write_str(mantissa)?;
81 f.write_str(" \\times 10^")?;
82 if exponent.len() == 1 {
83 // A lone digit needs no braces, and a lone digit is necessarily positive.
84 f.write_str(exponent)
85 } else {
86 f.write_char('{')?;
87 f.write_str(exponent)?;
88 f.write_char('}')
89 }
90 }
91}
92
93impl ToLatex for ComparableFloat {
94 /// Writes a [`ComparableFloat`] as a LaTeX math-mode fragment.
95 ///
96 /// The fragment is the wrapped [`Float`]'s own: the wrapper exists to give an equality and an
97 /// ordering that tell more [`Float`]s apart than the usual ones do, and does not change what
98 /// the value is.
99 ///
100 /// # Worst-case complexity
101 /// Same as the time and additional memory complexity of `fmt_latex` for [`Float`].
102 ///
103 /// # Examples
104 /// ```
105 /// use malachite_base::num::basic::traits::One;
106 /// use malachite_base::strings::latex::ToLatex;
107 /// use malachite_float::{ComparableFloat, Float};
108 ///
109 /// assert_eq!(ComparableFloat(Float::ONE).to_latex_string(), "1.0");
110 /// ```
111 #[inline]
112 fn fmt_latex(&self, f: &mut Formatter) -> Result {
113 self.0.fmt_latex(f)
114 }
115}
116
117impl ToLatex for ComparableFloatRef<'_> {
118 /// Writes a [`ComparableFloatRef`] as a LaTeX math-mode fragment.
119 ///
120 /// The fragment is the wrapped [`Float`]'s own: the wrapper exists to give an equality and an
121 /// ordering that tell more [`Float`]s apart than the usual ones do, and does not change what
122 /// the value is.
123 ///
124 /// # Worst-case complexity
125 /// Same as the time and additional memory complexity of `fmt_latex` for [`Float`].
126 ///
127 /// # Examples
128 /// ```
129 /// use malachite_base::num::basic::traits::One;
130 /// use malachite_base::strings::latex::ToLatex;
131 /// use malachite_float::{ComparableFloatRef, Float};
132 ///
133 /// let x = Float::ONE;
134 /// assert_eq!(ComparableFloatRef(&x).to_latex_string(), "1.0");
135 /// ```
136 #[inline]
137 fn fmt_latex(&self, f: &mut Formatter) -> Result {
138 self.0.fmt_latex(f)
139 }
140}