Skip to main content

malachite_base/num/basic/
traits.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Implementations of traits for NonZero* types by b4D8.
4//
5// This file is part of Malachite.
6//
7// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
8// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
9// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
10
11use core::num::*;
12
13/// Provides the constant 0.
14#[allow(clippy::declare_interior_mutable_const)]
15pub trait Zero {
16    const ZERO: Self;
17}
18
19/// Provides the constant 1.
20#[allow(clippy::declare_interior_mutable_const)]
21pub trait One {
22    const ONE: Self;
23}
24
25/// Provides the constant 2.
26#[allow(clippy::declare_interior_mutable_const)]
27pub trait Two {
28    const TWO: Self;
29}
30
31/// Provides the constant -1.
32#[allow(clippy::declare_interior_mutable_const)]
33pub trait NegativeOne {
34    const NEGATIVE_ONE: Self;
35}
36
37/// Provides the constant i, the imaginary unit.
38///
39/// No type in this crate implements this trait; it exists for complex types downstream, like
40/// Gaussian integers.
41#[allow(clippy::declare_interior_mutable_const)]
42pub trait I {
43    const I: Self;
44}
45
46/// Provides the constant -i, the negative of the imaginary unit.
47///
48/// No type in this crate implements this trait; it exists for complex types downstream, like
49/// Gaussian integers.
50#[allow(clippy::declare_interior_mutable_const)]
51pub trait NegativeI {
52    const NEGATIVE_I: Self;
53}
54
55/// Provides the constant 1/2.
56#[allow(clippy::declare_interior_mutable_const)]
57pub trait OneHalf {
58    const ONE_HALF: Self;
59}
60
61/// Provides the constant -0.
62#[allow(clippy::declare_interior_mutable_const)]
63pub trait NegativeZero {
64    const NEGATIVE_ZERO: Self;
65}
66
67/// Provides the constant (positive) Infinity.
68#[allow(clippy::declare_interior_mutable_const)]
69pub trait Infinity {
70    const INFINITY: Self;
71}
72
73/// Provides the constant -Infinity.
74#[allow(clippy::declare_interior_mutable_const)]
75pub trait NegativeInfinity {
76    const NEGATIVE_INFINITY: Self;
77}
78
79/// Provides the constant NaN.
80#[allow(clippy::declare_interior_mutable_const)]
81pub trait NaN {
82    const NAN: Self;
83}
84
85/// Provides the Prouhet-Thue-Morse constant, whose bits are the Thue-Morse sequence.
86pub trait ProuhetThueMorseConstant {
87    const PROUHET_THUE_MORSE_CONSTANT: Self;
88}
89
90/// Provides the prime constant, whose $n$th bit (starting from $n=1$) is true if and only if $n$ is
91/// prime.
92pub trait PrimeConstant {
93    const PRIME_CONSTANT: Self;
94}
95
96/// Provides $\ln 2$.
97pub trait Ln2 {
98    const LN_2: Self;
99}
100
101/// Provides $\ln 10$.
102pub trait Ln10 {
103    const LN_10: Self;
104}
105
106/// Provides $\log_2 e$.
107pub trait Log2E {
108    const LOG_2_E: Self;
109}
110
111/// Provides $\log_{10} e$.
112pub trait Log10E {
113    const LOG_10_E: Self;
114}
115
116/// Provides $\log_2 10$.
117pub trait Log210 {
118    const LOG_2_10: Self;
119}
120
121/// Provides $\log_{10} 2$.
122pub trait Log102 {
123    const LOG_10_2: Self;
124}
125
126/// Provides $\sqrt{2}$.
127pub trait Sqrt2 {
128    const SQRT_2: Self;
129}
130
131/// Provides $\sqrt{3}$.
132pub trait Sqrt3 {
133    const SQRT_3: Self;
134}
135
136/// Provides $\sqrt{5}$.
137pub trait Sqrt5 {
138    const SQRT_5: Self;
139}
140
141/// Provides $\sqrt{2}/2=\sqrt{1/2}=1/\sqrt{2}$.
142pub trait Sqrt2Over2 {
143    const SQRT_2_OVER_2: Self;
144}
145
146/// Provides $\sqrt{3}/3=\sqrt{1/3}=1/\sqrt{3}$.
147pub trait Sqrt3Over3 {
148    const SQRT_3_OVER_3: Self;
149}
150
151/// Provides $\sqrt{5}/5=\sqrt{1/5}=1/\sqrt{5}$.
152pub trait Sqrt5Over5 {
153    const SQRT_5_OVER_5: Self;
154}
155
156/// Provides $\varphi$, the golden ratio.
157pub trait Phi {
158    const PHI: Self;
159}
160
161/// Provides $\pi$.
162pub trait Pi {
163    const PI: Self;
164}
165
166/// Provides $\tau=2\pi$.
167pub trait Tau {
168    const TAU: Self;
169}
170
171/// Provides $\pi/2$.
172pub trait PiOver2 {
173    const PI_OVER_2: Self;
174}
175
176/// Provides $\pi/3$.
177pub trait PiOver3 {
178    const PI_OVER_3: Self;
179}
180
181/// Provides $\pi/4$.
182pub trait PiOver4 {
183    const PI_OVER_4: Self;
184}
185
186/// Provides $\pi/6$.
187pub trait PiOver6 {
188    const PI_OVER_6: Self;
189}
190
191/// Provides $\pi/8$.
192pub trait PiOver8 {
193    const PI_OVER_8: Self;
194}
195
196/// Provides $1/\pi$.
197pub trait OneOverPi {
198    const ONE_OVER_PI: Self;
199}
200
201/// Provides $\sqrt{\pi}$.
202pub trait SqrtPi {
203    const SQRT_PI: Self;
204}
205
206/// Provides $1/\sqrt{\pi}$.
207pub trait OneOverSqrtPi {
208    const ONE_OVER_SQRT_PI: Self;
209}
210
211/// Provides $1/\sqrt{\tau}=1/\sqrt{2\pi}$.
212pub trait OneOverSqrtTau {
213    const ONE_OVER_SQRT_TAU: Self;
214}
215
216/// Provides $2/\pi$.
217pub trait TwoOverPi {
218    const TWO_OVER_PI: Self;
219}
220
221/// Provides $2/\sqrt{\pi}$.
222pub trait TwoOverSqrtPi {
223    const TWO_OVER_SQRT_PI: Self;
224}
225
226/// Provides Catalan's constant, $G=\sum_{k=0}^\infty \frac{(-1)^k}{(2k+1)^2}$.
227pub trait CatalansConstant {
228    const CATALANS_CONSTANT: Self;
229}
230
231/// Provides the Champernowne constant in base 10, $0.123456789101112\ldots$, formed by
232/// concatenating the decimal representations of the positive integers.
233pub trait ChampernowneConstant {
234    const CHAMPERNOWNE_CONSTANT: Self;
235}
236
237/// Provides the Copeland–Erdős constant in base 10, $0.235711131719\ldots$, formed by
238/// concatenating the decimal representations of the primes.
239pub trait CopelandErdosConstant {
240    const COPELAND_ERDOS_CONSTANT: Self;
241}
242
243/// Provides Euler's constant (also known as the Euler–Mascheroni constant),
244/// $\gamma=\lim_{n\to\infty}\left(\sum_{k=1}^n\frac{1}{k}-\log n\right)$.
245pub trait EulersConstant {
246    const EULERS_CONSTANT: Self;
247}
248
249/// Provides Gauss's constant, $G=1/\mathrm{AGM}(1,\sqrt{2})$.
250///
251/// Having three consecutive esses in an identifier is awkward, so let's pretend that we sometimes
252/// use AP Style and write "Gauss' constant".
253pub trait GaussConstant {
254    const GAUSS_CONSTANT: Self;
255}
256
257/// Provides the Dottie number, the unique real fixed point of the cosine: the $d$ with $\cos d =
258/// d$, about 0.739.
259pub trait DottieNumber {
260    const DOTTIE_NUMBER: Self;
261}
262
263/// Provides Gelfond's constant, $e^\pi$.
264pub trait GelfondsConstant {
265    const GELFONDS_CONSTANT: Self;
266}
267
268/// Provides the Gelfond–Schneider constant, $2^{\sqrt 2}$.
269pub trait GelfondSchneiderConstant {
270    const GELFOND_SCHNEIDER_CONSTANT: Self;
271}
272
273/// Provides the lemniscate constant $\varpi=\pi G$, where $G$ is Gauss's constant.
274pub trait LemniscateConstant {
275    const LEMNISCATE_CONSTANT: Self;
276}
277
278/// Provides Liouville's constant in base 10, $\sum_{n=1}^{\infty} 10^{-n!}$, whose decimal
279/// expansion has a 1 at every position that is a factorial and a 0 everywhere else.
280pub trait LiouvillesConstant {
281    const LIOUVILLES_CONSTANT: Self;
282}
283
284/// Provides Ramanujan's constant, $e^{\pi\sqrt{163}}$.
285pub trait RamanujansConstant {
286    const RAMANUJANS_CONSTANT: Self;
287}
288
289// Implementation for `NonZero*` types:
290// - `One` and `Two` for both signed and unsigned variants
291// - `NegativeOne` for the signed variant
292macro_rules! impl_non_zero {
293    ($($t:ident),+) => {
294        $(
295            impl One for $t {
296                const ONE: Self = match Self::new(1) {
297                    Some(v) => v,
298                    None => unreachable!() // 1 is a valid nonzero value
299                };
300            }
301
302            impl Two for $t {
303                const TWO: Self = match Self::new(2) {
304                    Some(v) => v,
305                    None => unreachable!() // 2 is a valid nonzero value
306                };
307            }
308        )+
309    };
310    ($($u:ident && $i:ident),+) => {
311        $(
312            impl_non_zero!($u, $i);
313
314            impl NegativeOne for $i {
315                const NEGATIVE_ONE: Self = match Self::new(-1) {
316                    Some(v) => v,
317                    None => unreachable!() // -1 is a valid non zero value
318                };
319            }
320        )+
321    }
322}
323
324impl_non_zero!(
325    NonZeroUsize && NonZeroIsize,
326    NonZeroU128 && NonZeroI128,
327    NonZeroU64 && NonZeroI64,
328    NonZeroU32 && NonZeroI32,
329    NonZeroU16 && NonZeroI16,
330    NonZeroU8 && NonZeroI8
331);