malachite_float/basic/
constants.rs

1// Copyright © 2025 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 crate::InnerFloat::{Finite, Infinity, NaN, Zero};
11use malachite_base::comparison::traits::{Max, Min};
12use malachite_base::named::Named;
13use malachite_base::num::arithmetic::traits::{
14    NegModPowerOf2, PowerOf2, RoundToMultipleOfPowerOf2,
15};
16use malachite_base::num::basic::integers::PrimitiveInt;
17use malachite_base::num::basic::traits::{
18    Infinity as InfinityTrait, NaN as NaNTrait, NegativeInfinity, NegativeOne, NegativeZero, One,
19    OneHalf, Two, Zero as ZeroTrait,
20};
21use malachite_base::num::logic::traits::LowMask;
22use malachite_base::rounding_modes::RoundingMode::*;
23use malachite_nz::natural::Natural;
24use malachite_nz::platform::Limb;
25
26#[doc(hidden)]
27#[macro_export]
28macro_rules! float_zero {
29    () => {
30        Float(Zero { sign: true })
31    };
32}
33
34#[doc(hidden)]
35#[macro_export]
36macro_rules! float_one {
37    () => {
38        Float(Finite {
39            sign: true,
40            exponent: 1,
41            precision: 1,
42            significand: Natural::HIGH_BIT,
43        })
44    };
45}
46
47#[doc(hidden)]
48#[macro_export]
49macro_rules! float_two {
50    () => {
51        Float(Finite {
52            sign: true,
53            exponent: 2,
54            precision: 1,
55            significand: Natural::HIGH_BIT,
56        })
57    };
58}
59
60#[doc(hidden)]
61#[macro_export]
62macro_rules! float_negative_one {
63    () => {
64        Float(Finite {
65            sign: false,
66            exponent: 1,
67            precision: 1,
68            significand: Natural::HIGH_BIT,
69        })
70    };
71}
72
73#[doc(hidden)]
74#[macro_export]
75macro_rules! float_one_half {
76    () => {
77        Float(Finite {
78            sign: true,
79            exponent: 0,
80            precision: 1,
81            significand: Natural::HIGH_BIT,
82        })
83    };
84}
85
86#[doc(hidden)]
87#[macro_export]
88macro_rules! float_negative_zero {
89    () => {
90        Float(Zero { sign: false })
91    };
92}
93
94#[doc(hidden)]
95#[macro_export]
96macro_rules! float_infinity {
97    () => {
98        Float(Infinity { sign: true })
99    };
100}
101
102#[doc(hidden)]
103#[macro_export]
104macro_rules! float_negative_infinity {
105    () => {
106        Float(Infinity { sign: false })
107    };
108}
109
110#[doc(hidden)]
111#[macro_export]
112macro_rules! float_nan {
113    () => {
114        Float(NaN)
115    };
116}
117
118#[doc(hidden)]
119#[macro_export]
120macro_rules! float_finite {
121    () => {
122        Float(Finite { .. })
123    };
124}
125
126#[doc(hidden)]
127#[macro_export]
128macro_rules! float_either_infinity {
129    () => {
130        Float(Infinity { .. })
131    };
132}
133
134#[doc(hidden)]
135#[macro_export]
136macro_rules! float_either_zero {
137    () => {
138        Float(Zero { .. })
139    };
140}
141
142/// The constant 0.0 (positive zero), with precision 1.
143impl ZeroTrait for Float {
144    const ZERO: Self = float_zero!();
145}
146
147/// The constant 1.0, with precision 1.
148impl One for Float {
149    const ONE: Self = float_one!();
150}
151
152/// The constant 2.0, with precision 1.
153impl Two for Float {
154    const TWO: Self = float_two!();
155}
156
157/// The constant -1.0, with precision 1.
158impl NegativeOne for Float {
159    const NEGATIVE_ONE: Self = float_negative_one!();
160}
161
162/// The constant 0.5, with precision 1.
163impl OneHalf for Float {
164    const ONE_HALF: Self = float_one_half!();
165}
166
167/// The constant -0.0, with precision 1.
168impl NegativeZero for Float {
169    const NEGATIVE_ZERO: Self = float_negative_zero!();
170}
171
172/// The constant $\infty$.
173impl InfinityTrait for Float {
174    const INFINITY: Self = float_infinity!();
175}
176
177/// The constant $-\infty$.
178impl NegativeInfinity for Float {
179    const NEGATIVE_INFINITY: Self = float_negative_infinity!();
180}
181
182/// The constant NaN.
183impl NaNTrait for Float {
184    const NAN: Self = float_nan!();
185}
186
187impl Default for Float {
188    /// The default value of a [`Float`], NaN.
189    fn default() -> Self {
190        Self::NAN
191    }
192}
193
194/// The lowest value representable by this type, $-\infty$.
195impl Min for Float {
196    const MIN: Self = Self::NEGATIVE_INFINITY;
197}
198
199/// The highest value representable by this type, $\infty$.
200impl Max for Float {
201    const MAX: Self = Self::INFINITY;
202}
203
204// Implements `Named` for `Float`.
205impl_named!(Float);
206
207impl Float {
208    /// The minimum representable positive value, or $2^{-2^{30}}$, with precision 1.
209    pub const MIN_POSITIVE: Self = Self(Finite {
210        sign: true,
211        exponent: Self::MIN_EXPONENT,
212        precision: 1,
213        significand: Natural::HIGH_BIT,
214    });
215
216    /// Returns the minimum representable positive value, or $2^{-2^{30}}$, with the given
217    /// precision.
218    ///
219    /// $$
220    /// f(p) = 2^{-2^{30}},
221    /// $$
222    ///
223    /// and the output has precision `prec`.
224    ///
225    /// # Worst-case complexity
226    /// $T(n) = O(n)$
227    ///
228    /// $M(n) = O(n)$
229    ///
230    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
231    ///
232    /// # Panics
233    /// Panics if `prec` is zero.
234    ///
235    /// # Examples
236    /// ```
237    /// use malachite_float::Float;
238    ///
239    /// assert_eq!(Float::min_positive_value_prec(1).to_string(), "too_small");
240    /// assert_eq!(Float::min_positive_value_prec(10).to_string(), "too_small");
241    /// assert_eq!(Float::min_positive_value_prec(100).to_string(), "too_small");
242    ///
243    /// assert_eq!(Float::min_positive_value_prec(1).get_prec(), Some(1));
244    /// assert_eq!(Float::min_positive_value_prec(10).get_prec(), Some(10));
245    /// assert_eq!(Float::min_positive_value_prec(100).get_prec(), Some(100));
246    /// ```
247    pub fn min_positive_value_prec(prec: u64) -> Self {
248        assert_ne!(prec, 0);
249        Self(Finite {
250            sign: true,
251            exponent: Self::MIN_EXPONENT,
252            precision: prec,
253            significand: Natural::power_of_2(
254                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
255                    .0
256                    - 1,
257            ),
258        })
259    }
260
261    /// There is no maximum finite [`Float`], but there is one for any given precision. This
262    /// function returns that [`Float`].
263    ///
264    /// $$
265    /// f(p) = (1-(1/2)^p)2^{2^{30}-1},
266    /// $$
267    /// where $p$ is the `prec`. The output has precision `prec`.
268    ///
269    /// # Worst-case complexity
270    /// $T(n) = O(n)$
271    ///
272    /// $M(n) = O(n)$
273    ///
274    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
275    ///
276    /// # Panics
277    /// Panics if `prec` is zero.
278    ///
279    /// # Examples
280    /// ```
281    /// use malachite_float::Float;
282    ///
283    /// assert_eq!(Float::max_finite_value_with_prec(1).to_string(), "too_big");
284    /// assert_eq!(Float::max_finite_value_with_prec(10).to_string(), "too_big");
285    /// assert_eq!(
286    ///     Float::max_finite_value_with_prec(100).to_string(),
287    ///     "too_big"
288    /// );
289    ///
290    /// assert_eq!(Float::max_finite_value_with_prec(1).get_prec(), Some(1));
291    /// assert_eq!(Float::max_finite_value_with_prec(10).get_prec(), Some(10));
292    /// assert_eq!(Float::max_finite_value_with_prec(100).get_prec(), Some(100));
293    /// ```
294    pub fn max_finite_value_with_prec(prec: u64) -> Self {
295        assert_ne!(prec, 0);
296        Self(Finite {
297            sign: true,
298            exponent: Self::MAX_EXPONENT,
299            precision: prec,
300            significand: Natural::low_mask(prec) << prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
301        })
302    }
303
304    /// Returns the number 1, with the given precision.
305    ///
306    /// $$
307    /// f(p) = 1,
308    /// $$
309    ///
310    /// and the output has precision $p$.
311    ///
312    /// # Worst-case complexity
313    /// $T(n) = O(n)$
314    ///
315    /// $M(n) = O(n)$
316    ///
317    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
318    ///
319    /// # Panics
320    /// Panics if `prec` is zero.
321    ///
322    /// # Examples
323    /// ```
324    /// use malachite_float::Float;
325    ///
326    /// assert_eq!(Float::one_prec(1), 1);
327    /// assert_eq!(Float::one_prec(10), 1);
328    /// assert_eq!(Float::one_prec(100), 1);
329    ///
330    /// assert_eq!(Float::one_prec(1).get_prec(), Some(1));
331    /// assert_eq!(Float::one_prec(10).get_prec(), Some(10));
332    /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
333    /// ```
334    pub fn one_prec(prec: u64) -> Self {
335        assert_ne!(prec, 0);
336        Self(Finite {
337            sign: true,
338            exponent: 1,
339            precision: prec,
340            significand: Natural::power_of_2(
341                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
342                    .0
343                    - 1,
344            ),
345        })
346    }
347
348    /// Returns the number 2, with the given precision.
349    ///
350    /// $$
351    /// f(p) = 2,
352    /// $$
353    ///
354    /// and the output has precision $p$.
355    ///
356    /// # Worst-case complexity
357    /// $T(n) = O(n)$
358    ///
359    /// $M(n) = O(n)$
360    ///
361    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
362    ///
363    /// # Panics
364    /// Panics if `prec` is zero.
365    ///
366    /// # Examples
367    /// ```
368    /// use malachite_float::Float;
369    ///
370    /// assert_eq!(Float::two_prec(1), 2);
371    /// assert_eq!(Float::two_prec(10), 2);
372    /// assert_eq!(Float::two_prec(100), 2);
373    ///
374    /// assert_eq!(Float::two_prec(1).get_prec(), Some(1));
375    /// assert_eq!(Float::two_prec(10).get_prec(), Some(10));
376    /// assert_eq!(Float::two_prec(100).get_prec(), Some(100));
377    /// ```
378    pub fn two_prec(prec: u64) -> Self {
379        assert_ne!(prec, 0);
380        Self(Finite {
381            sign: true,
382            exponent: 2,
383            precision: prec,
384            significand: Natural::power_of_2(
385                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
386                    .0
387                    - 1,
388            ),
389        })
390    }
391
392    /// Returns the number $-1$, with the given precision.
393    ///
394    /// $$
395    /// f(p) = -1,
396    /// $$
397    ///
398    /// and the output has precision $p$.
399    ///
400    /// # Worst-case complexity
401    /// $T(n) = O(n)$
402    ///
403    /// $M(n) = O(n)$
404    ///
405    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
406    ///
407    /// # Panics
408    /// Panics if `prec` is zero.
409    ///
410    /// # Examples
411    /// ```
412    /// use malachite_float::Float;
413    ///
414    /// assert_eq!(Float::negative_one_prec(1), -1);
415    /// assert_eq!(Float::negative_one_prec(10), -1);
416    /// assert_eq!(Float::negative_one_prec(100), -1);
417    ///
418    /// assert_eq!(Float::negative_one_prec(1).get_prec(), Some(1));
419    /// assert_eq!(Float::negative_one_prec(10).get_prec(), Some(10));
420    /// assert_eq!(Float::negative_one_prec(100).get_prec(), Some(100));
421    /// ```
422    pub fn negative_one_prec(prec: u64) -> Self {
423        assert_ne!(prec, 0);
424        Self(Finite {
425            sign: false,
426            exponent: 1,
427            precision: prec,
428            significand: Natural::power_of_2(
429                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
430                    .0
431                    - 1,
432            ),
433        })
434    }
435
436    /// Returns the number 0.5, with the given precision.
437    ///
438    /// $$
439    /// f(p) = 0.5,
440    /// $$
441    ///
442    /// and the output has precision $p$.
443    ///
444    /// # Worst-case complexity
445    /// $T(n) = O(n)$
446    ///
447    /// $M(n) = O(n)$
448    ///
449    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
450    ///
451    /// # Panics
452    /// Panics if `prec` is zero.
453    ///
454    /// # Examples
455    /// ```
456    /// use malachite_float::Float;
457    ///
458    /// assert_eq!(Float::one_half_prec(1), 0.5);
459    /// assert_eq!(Float::one_half_prec(10), 0.5);
460    /// assert_eq!(Float::one_half_prec(100), 0.5);
461    ///
462    /// assert_eq!(Float::one_half_prec(1).get_prec(), Some(1));
463    /// assert_eq!(Float::one_half_prec(10).get_prec(), Some(10));
464    /// assert_eq!(Float::one_half_prec(100).get_prec(), Some(100));
465    /// ```
466    pub fn one_half_prec(prec: u64) -> Self {
467        assert_ne!(prec, 0);
468        Self(Finite {
469            sign: true,
470            exponent: 0,
471            precision: prec,
472            significand: Natural::power_of_2(
473                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
474                    .0
475                    - 1,
476            ),
477        })
478    }
479}