Skip to main content

malachite_float/basic/
constants.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 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    IsPowerOf2, 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::{BitScan, 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    /// Returns whether the absolute value of a `Float` is equal to the minimum representable
262    /// positive value, or $2^{-2^{30}}$.
263    ///
264    /// $$
265    /// f(x) = (|x|=2^{-2^{30}}).
266    /// $$
267    ///
268    /// # Worst-case complexity
269    /// $T(n) = O(n)$
270    ///
271    /// $M(n) = O(1)$
272    ///
273    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
274    ///
275    /// # Examples
276    /// ```
277    /// use malachite_float::Float;
278    ///
279    /// assert!(Float::min_positive_value_prec(100).abs_is_min_positive_value());
280    /// assert!((-Float::min_positive_value_prec(100)).abs_is_min_positive_value());
281    /// assert!(!(Float::min_positive_value_prec(100) << 1u32).abs_is_min_positive_value());
282    /// ```
283    pub fn abs_is_min_positive_value(&self) -> bool {
284        self.get_exponent() == Some(Self::MIN_EXPONENT)
285            && self.significand_ref().unwrap().is_power_of_2()
286    }
287
288    /// There is no maximum finite [`Float`], but there is one for any given precision. This
289    /// function returns that [`Float`].
290    ///
291    /// $$
292    /// f(p) = (1-(1/2)^p)2^{2^{30}-1},
293    /// $$
294    /// where $p$ is `prec`. The output has precision `prec`.
295    ///
296    /// # Worst-case complexity
297    /// $T(n) = O(n)$
298    ///
299    /// $M(n) = O(n)$
300    ///
301    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
302    ///
303    /// # Panics
304    /// Panics if `prec` is zero.
305    ///
306    /// # Examples
307    /// ```
308    /// use malachite_float::Float;
309    ///
310    /// assert_eq!(Float::max_finite_value_with_prec(1).to_string(), "too_big");
311    /// assert_eq!(Float::max_finite_value_with_prec(10).to_string(), "too_big");
312    /// assert_eq!(
313    ///     Float::max_finite_value_with_prec(100).to_string(),
314    ///     "too_big"
315    /// );
316    ///
317    /// assert_eq!(Float::max_finite_value_with_prec(1).get_prec(), Some(1));
318    /// assert_eq!(Float::max_finite_value_with_prec(10).get_prec(), Some(10));
319    /// assert_eq!(Float::max_finite_value_with_prec(100).get_prec(), Some(100));
320    /// ```
321    pub fn max_finite_value_with_prec(prec: u64) -> Self {
322        assert_ne!(prec, 0);
323        Self(Finite {
324            sign: true,
325            exponent: Self::MAX_EXPONENT,
326            precision: prec,
327            significand: Natural::low_mask(prec) << prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
328        })
329    }
330
331    /// Returns whether the absolute value of a `Float` is equal to the maximum representable finite
332    /// value with that precision.
333    ///
334    /// $$
335    /// f(x) = (|x|=(1-(1/2)^p)2^{2^{30}-1}),
336    /// $$
337    /// where $p$ is the precision of the $x$.
338    ///
339    /// # Worst-case complexity
340    /// $T(n) = O(n)$
341    ///
342    /// $M(n) = O(1)$
343    ///
344    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
345    ///
346    /// # Examples
347    /// ```
348    /// use malachite_float::Float;
349    ///
350    /// assert!(Float::max_finite_value_with_prec(100).abs_is_max_finite_value_with_prec());
351    /// assert!((-Float::max_finite_value_with_prec(100)).abs_is_max_finite_value_with_prec());
352    /// assert!(
353    ///     !(Float::max_finite_value_with_prec(100) >> 1u32).abs_is_max_finite_value_with_prec()
354    /// );
355    /// ```
356    pub fn abs_is_max_finite_value_with_prec(&self) -> bool {
357        if self.get_exponent() != Some(Self::MAX_EXPONENT) {
358            return false;
359        }
360        let prec = self.get_prec().unwrap();
361        let lowest_1_index = prec.neg_mod_power_of_2(Limb::LOG_WIDTH);
362        self.significand_ref()
363            .unwrap()
364            .index_of_next_false_bit(lowest_1_index)
365            .unwrap()
366            == prec
367                .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
368                .0
369    }
370
371    /// Returns the number 1, with the given precision.
372    ///
373    /// $$
374    /// f(p) = 1,
375    /// $$
376    ///
377    /// and the output has precision $p$.
378    ///
379    /// # Worst-case complexity
380    /// $T(n) = O(n)$
381    ///
382    /// $M(n) = O(n)$
383    ///
384    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
385    ///
386    /// # Panics
387    /// Panics if `prec` is zero.
388    ///
389    /// # Examples
390    /// ```
391    /// use malachite_float::Float;
392    ///
393    /// assert_eq!(Float::one_prec(1), 1);
394    /// assert_eq!(Float::one_prec(10), 1);
395    /// assert_eq!(Float::one_prec(100), 1);
396    ///
397    /// assert_eq!(Float::one_prec(1).get_prec(), Some(1));
398    /// assert_eq!(Float::one_prec(10).get_prec(), Some(10));
399    /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
400    /// ```
401    pub fn one_prec(prec: u64) -> Self {
402        assert_ne!(prec, 0);
403        Self(Finite {
404            sign: true,
405            exponent: 1,
406            precision: prec,
407            significand: Natural::power_of_2(
408                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
409                    .0
410                    - 1,
411            ),
412        })
413    }
414
415    /// Returns the number 2, with the given precision.
416    ///
417    /// $$
418    /// f(p) = 2,
419    /// $$
420    ///
421    /// and the output has precision $p$.
422    ///
423    /// # Worst-case complexity
424    /// $T(n) = O(n)$
425    ///
426    /// $M(n) = O(n)$
427    ///
428    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
429    ///
430    /// # Panics
431    /// Panics if `prec` is zero.
432    ///
433    /// # Examples
434    /// ```
435    /// use malachite_float::Float;
436    ///
437    /// assert_eq!(Float::two_prec(1), 2);
438    /// assert_eq!(Float::two_prec(10), 2);
439    /// assert_eq!(Float::two_prec(100), 2);
440    ///
441    /// assert_eq!(Float::two_prec(1).get_prec(), Some(1));
442    /// assert_eq!(Float::two_prec(10).get_prec(), Some(10));
443    /// assert_eq!(Float::two_prec(100).get_prec(), Some(100));
444    /// ```
445    pub fn two_prec(prec: u64) -> Self {
446        assert_ne!(prec, 0);
447        Self(Finite {
448            sign: true,
449            exponent: 2,
450            precision: prec,
451            significand: Natural::power_of_2(
452                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
453                    .0
454                    - 1,
455            ),
456        })
457    }
458
459    /// Returns the number $-1$, with the given precision.
460    ///
461    /// $$
462    /// f(p) = -1,
463    /// $$
464    ///
465    /// and the output has precision $p$.
466    ///
467    /// # Worst-case complexity
468    /// $T(n) = O(n)$
469    ///
470    /// $M(n) = O(n)$
471    ///
472    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
473    ///
474    /// # Panics
475    /// Panics if `prec` is zero.
476    ///
477    /// # Examples
478    /// ```
479    /// use malachite_float::Float;
480    ///
481    /// assert_eq!(Float::negative_one_prec(1), -1);
482    /// assert_eq!(Float::negative_one_prec(10), -1);
483    /// assert_eq!(Float::negative_one_prec(100), -1);
484    ///
485    /// assert_eq!(Float::negative_one_prec(1).get_prec(), Some(1));
486    /// assert_eq!(Float::negative_one_prec(10).get_prec(), Some(10));
487    /// assert_eq!(Float::negative_one_prec(100).get_prec(), Some(100));
488    /// ```
489    pub fn negative_one_prec(prec: u64) -> Self {
490        assert_ne!(prec, 0);
491        Self(Finite {
492            sign: false,
493            exponent: 1,
494            precision: prec,
495            significand: Natural::power_of_2(
496                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
497                    .0
498                    - 1,
499            ),
500        })
501    }
502
503    /// Returns the number 0.5, with the given precision.
504    ///
505    /// $$
506    /// f(p) = 0.5,
507    /// $$
508    ///
509    /// and the output has precision $p$.
510    ///
511    /// # Worst-case complexity
512    /// $T(n) = O(n)$
513    ///
514    /// $M(n) = O(n)$
515    ///
516    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
517    ///
518    /// # Panics
519    /// Panics if `prec` is zero.
520    ///
521    /// # Examples
522    /// ```
523    /// use malachite_float::Float;
524    ///
525    /// assert_eq!(Float::one_half_prec(1), 0.5);
526    /// assert_eq!(Float::one_half_prec(10), 0.5);
527    /// assert_eq!(Float::one_half_prec(100), 0.5);
528    ///
529    /// assert_eq!(Float::one_half_prec(1).get_prec(), Some(1));
530    /// assert_eq!(Float::one_half_prec(10).get_prec(), Some(10));
531    /// assert_eq!(Float::one_half_prec(100).get_prec(), Some(100));
532    /// ```
533    pub fn one_half_prec(prec: u64) -> Self {
534        assert_ne!(prec, 0);
535        Self(Finite {
536            sign: true,
537            exponent: 0,
538            precision: prec,
539            significand: Natural::power_of_2(
540                prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
541                    .0
542                    - 1,
543            ),
544        })
545    }
546}