Skip to main content

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