Skip to main content

malachite_float/float/exhaustive/
mod.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;
11use alloc::vec::IntoIter;
12use core::iter::{Chain, Once, once};
13use core::mem::swap;
14use malachite_base::iterators::bit_distributor::BitDistributorOutputType;
15use malachite_base::num::arithmetic::traits::{NegModPowerOf2, PowerOf2};
16use malachite_base::num::basic::integers::PrimitiveInt;
17use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, NegativeZero, Zero};
18use malachite_base::num::exhaustive::{
19    ExhaustiveSignedRange, PrimitiveIntIncreasingRange, exhaustive_signed_inclusive_range,
20    primitive_int_increasing_inclusive_range,
21};
22use malachite_base::num::iterators::{BitDistributorSequence, bit_distributor_sequence};
23use malachite_base::num::logic::traits::{LowMask, NotAssign};
24use malachite_base::tuples::exhaustive::{
25    ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, LexDependentPairs,
26    exhaustive_dependent_pairs, lex_dependent_pairs,
27};
28use malachite_nz::natural::Natural;
29use malachite_nz::natural::exhaustive::{
30    ExhaustiveNaturalRange, exhaustive_natural_inclusive_range,
31};
32use malachite_nz::platform::Limb;
33
34/// Generates all finite positive [`Float`]s with a specified `sci_exponent` (one less than the raw
35/// exponent) and precision.
36///
37/// This `struct` is created by [`exhaustive_positive_floats_with_sci_exponent_and_precision`]; see
38/// its documentation for more.
39#[derive(Clone, Debug)]
40pub struct ExhaustivePositiveFloatsWithSciExponentAndPrecision {
41    exponent: i32,
42    precision: u64,
43    shift: u64,
44    significands: ExhaustiveNaturalRange,
45}
46
47impl Iterator for ExhaustivePositiveFloatsWithSciExponentAndPrecision {
48    type Item = Float;
49
50    #[inline]
51    fn next(&mut self) -> Option<Float> {
52        self.significands.next().map(|s| {
53            Float(Finite {
54                sign: true,
55                exponent: self.exponent,
56                precision: self.precision,
57                significand: s << self.shift,
58            })
59        })
60    }
61}
62
63/// Generates all finite positive [`Float`]s with a specified `sci_exponent` (one less than the raw
64/// exponent) and precision.
65///
66/// Positive and negative zero are both excluded.
67///
68/// A finite positive [`Float`] may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s < 2$
69/// and $e_s$ is an integer; then $e_s$ is the sci-exponent.
70///
71/// The output length is $2^{p-1}$.
72///
73/// # Worst-case complexity
74/// $T(n) = O(n)$
75///
76/// $M(n) = O(n)$
77///
78/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
79///
80/// # Panics
81/// Panics if the precision is zero.
82///
83/// # Examples
84/// ```
85/// use itertools::Itertools;
86/// use malachite_float::float::exhaustive::*;
87/// use malachite_float::ComparableFloat;
88///
89/// // The number after the '#' is the precision.
90/// assert_eq!(
91///     exhaustive_positive_floats_with_sci_exponent_and_precision(0, 4)
92///         .map(|f| ComparableFloat(f).to_string())
93///         .collect_vec()
94///         .as_slice(),
95///     &["1.00#4", "1.12#4", "1.25#4", "1.38#4", "1.50#4", "1.62#4", "1.75#4", "1.88#4"]
96/// );
97///
98/// assert_eq!(
99///     exhaustive_positive_floats_with_sci_exponent_and_precision(2, 5)
100///         .map(|f| ComparableFloat(f).to_string())
101///         .collect_vec()
102///         .as_slice(),
103///     &[
104///         "4.00#5", "4.25#5", "4.50#5", "4.75#5", "5.00#5", "5.25#5", "5.50#5", "5.75#5",
105///         "6.00#5", "6.25#5", "6.50#5", "6.75#5", "7.00#5", "7.25#5", "7.50#5", "7.75#5"
106///     ]
107/// );
108/// ```
109pub fn exhaustive_positive_floats_with_sci_exponent_and_precision(
110    sci_exponent: i32,
111    prec: u64,
112) -> ExhaustivePositiveFloatsWithSciExponentAndPrecision {
113    assert!(sci_exponent < Float::MAX_EXPONENT);
114    assert!(sci_exponent >= Float::MIN_EXPONENT_MINUS_1);
115    assert_ne!(prec, 0);
116    ExhaustivePositiveFloatsWithSciExponentAndPrecision {
117        exponent: sci_exponent + 1,
118        precision: prec,
119        shift: prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
120        significands: exhaustive_natural_inclusive_range(
121            Natural::power_of_2(prec - 1),
122            Natural::low_mask(prec),
123        ),
124    }
125}
126
127#[derive(Clone, Debug)]
128struct FloatsWithSciExponentAndPrecisionGenerator {
129    sci_exponent: i32,
130}
131
132impl
133    ExhaustiveDependentPairsYsGenerator<
134        u64,
135        Float,
136        ExhaustivePositiveFloatsWithSciExponentAndPrecision,
137    > for FloatsWithSciExponentAndPrecisionGenerator
138{
139    #[inline]
140    fn get_ys(&self, &prec: &u64) -> ExhaustivePositiveFloatsWithSciExponentAndPrecision {
141        exhaustive_positive_floats_with_sci_exponent_and_precision(self.sci_exponent, prec)
142    }
143}
144
145#[inline]
146fn exhaustive_positive_floats_with_sci_exponent_helper(
147    sci_exponent: i32,
148) -> LexDependentPairs<
149    u64,
150    Float,
151    FloatsWithSciExponentAndPrecisionGenerator,
152    PrimitiveIntIncreasingRange<u64>,
153    ExhaustivePositiveFloatsWithSciExponentAndPrecision,
154> {
155    lex_dependent_pairs(
156        primitive_int_increasing_inclusive_range(1, u64::MAX),
157        FloatsWithSciExponentAndPrecisionGenerator { sci_exponent },
158    )
159}
160
161/// Generates all finite positive [`Float`]s with a specified `sci_exponent` (one less than the raw
162/// exponent).
163///
164/// This `struct` is created by [`exhaustive_positive_floats_with_sci_exponent`]; see its
165/// documentation for more.
166#[derive(Clone, Debug)]
167pub struct ExhaustivePositiveFloatsWithSciExponent(
168    LexDependentPairs<
169        u64,
170        Float,
171        FloatsWithSciExponentAndPrecisionGenerator,
172        PrimitiveIntIncreasingRange<u64>,
173        ExhaustivePositiveFloatsWithSciExponentAndPrecision,
174    >,
175);
176
177impl Iterator for ExhaustivePositiveFloatsWithSciExponent {
178    type Item = Float;
179
180    #[inline]
181    fn next(&mut self) -> Option<Float> {
182        self.0.next().map(|p| p.1)
183    }
184}
185
186/// Generates all finite positive [`Float`]s with a specified `sci_exponent` (one less than the raw
187/// exponent).
188///
189/// Positive and negative zero are both excluded.
190///
191/// A finite positive [`Float`] may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s < 2$
192/// and $e_s$ is an integer; then $e_s$ is the sci-exponent.
193///
194/// The output length is infinite.
195///
196/// # Worst-case complexity per iteration
197/// $T(i) = O(\log i)$
198///
199/// $M(i) = O(\log i)$
200///
201/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
202///
203/// # Panics
204/// Panics if the precision is zero.
205///
206/// # Examples
207/// ```
208/// use itertools::Itertools;
209/// use malachite_float::float::exhaustive::exhaustive_positive_floats_with_sci_exponent;
210/// use malachite_float::ComparableFloat;
211///
212/// // The number after the '#' is the precision.
213/// assert_eq!(
214///     exhaustive_positive_floats_with_sci_exponent(0)
215///         .take(20)
216///         .map(|f| ComparableFloat(f).to_string())
217///         .collect_vec()
218///         .as_slice(),
219///     &[
220///         "1.0#1", "1.0#2", "1.5#2", "1.0#3", "1.2#3", "1.5#3", "1.8#3", "1.00#4", "1.12#4",
221///         "1.25#4", "1.38#4", "1.50#4", "1.62#4", "1.75#4", "1.88#4", "1.00#5", "1.06#5",
222///         "1.12#5", "1.19#5", "1.25#5"
223///     ]
224/// );
225///
226/// assert_eq!(
227///     exhaustive_positive_floats_with_sci_exponent(2)
228///         .take(20)
229///         .map(|f| ComparableFloat(f).to_string())
230///         .collect_vec()
231///         .as_slice(),
232///     &[
233///         "4.0#1", "4.0#2", "6.0#2", "4.0#3", "5.0#3", "6.0#3", "7.0#3", "4.00#4", "4.50#4",
234///         "5.00#4", "5.50#4", "6.00#4", "6.50#4", "7.00#4", "7.50#4", "4.00#5", "4.25#5",
235///         "4.50#5", "4.75#5", "5.00#5"
236///     ]
237/// );
238/// ```
239#[inline]
240pub fn exhaustive_positive_floats_with_sci_exponent(
241    sci_exponent: i32,
242) -> ExhaustivePositiveFloatsWithSciExponent {
243    assert!(sci_exponent < Float::MAX_EXPONENT);
244    assert!(sci_exponent >= Float::MIN_EXPONENT_MINUS_1);
245    ExhaustivePositiveFloatsWithSciExponent(exhaustive_positive_floats_with_sci_exponent_helper(
246        sci_exponent,
247    ))
248}
249
250#[derive(Clone, Debug)]
251struct FloatsWithPrecisionAndSciExponentGenerator {
252    precision: u64,
253}
254
255impl
256    ExhaustiveDependentPairsYsGenerator<
257        i32,
258        Float,
259        ExhaustivePositiveFloatsWithSciExponentAndPrecision,
260    > for FloatsWithPrecisionAndSciExponentGenerator
261{
262    #[inline]
263    fn get_ys(&self, &exp: &i32) -> ExhaustivePositiveFloatsWithSciExponentAndPrecision {
264        exhaustive_positive_floats_with_sci_exponent_and_precision(exp, self.precision)
265    }
266}
267
268#[inline]
269fn exhaustive_floats_with_precision_helper(
270    prec: u64,
271) -> ExhaustiveDependentPairs<
272    i32,
273    Float,
274    BitDistributorSequence,
275    FloatsWithPrecisionAndSciExponentGenerator,
276    ExhaustiveSignedRange<i32>,
277    ExhaustivePositiveFloatsWithSciExponentAndPrecision,
278> {
279    exhaustive_dependent_pairs(
280        bit_distributor_sequence(
281            BitDistributorOutputType::normal(1),
282            BitDistributorOutputType::normal(1),
283        ),
284        exhaustive_signed_inclusive_range(Float::MIN_EXPONENT, Float::MAX_EXPONENT),
285        FloatsWithPrecisionAndSciExponentGenerator { precision: prec },
286    )
287}
288
289/// Generates all finite positive [`Float`]s with a specified precision.
290///
291/// This `struct` is created by [`exhaustive_positive_floats_with_precision`]; see its documentation
292/// for more.
293#[derive(Clone, Debug)]
294pub struct ExhaustivePositiveFloatsWithPrecision(
295    ExhaustiveDependentPairs<
296        i32,
297        Float,
298        BitDistributorSequence,
299        FloatsWithPrecisionAndSciExponentGenerator,
300        ExhaustiveSignedRange<i32>,
301        ExhaustivePositiveFloatsWithSciExponentAndPrecision,
302    >,
303);
304
305impl Iterator for ExhaustivePositiveFloatsWithPrecision {
306    type Item = Float;
307
308    #[inline]
309    fn next(&mut self) -> Option<Float> {
310        self.0.next().map(|p| p.1)
311    }
312}
313
314/// Generates all finite positive [`Float`]s with a specified `precision`.
315///
316/// Positive and negative zero are both excluded.
317///
318/// The output length is infinite.
319///
320/// # Worst-case complexity per iteration
321/// $T(i) = O(\log i)$
322///
323/// $M(i) = O(\log i)$
324///
325/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
326///
327/// # Panics
328/// Panics if the precision is zero.
329///
330/// # Examples
331/// ```
332/// use itertools::Itertools;
333/// use malachite_float::float::exhaustive::exhaustive_positive_floats_with_precision;
334/// use malachite_float::ComparableFloat;
335///
336/// // The number after the '#' is the precision.
337/// assert_eq!(
338///     exhaustive_positive_floats_with_precision(1)
339///         .take(20)
340///         .map(|f| ComparableFloat(f).to_string())
341///         .collect_vec()
342///         .as_slice(),
343///     &[
344///         "1.0#1", "2.0#1", "0.50#1", "4.0#1", "0.25#1", "8.0#1", "0.12#1", "16.0#1", "0.062#1",
345///         "32.0#1", "0.031#1", "64.0#1", "0.016#1", "1.3e2#1", "0.0078#1", "2.6e2#1", "0.0039#1",
346///         "5.1e2#1", "0.0020#1", "1.0e3#1"
347///     ]
348/// );
349///
350/// assert_eq!(
351///     exhaustive_positive_floats_with_precision(10)
352///         .take(20)
353///         .map(|f| ComparableFloat(f).to_string())
354///         .collect_vec()
355///         .as_slice(),
356///     &[
357///         "1.0000#10",
358///         "2.0000#10",
359///         "1.0020#10",
360///         "2.0039#10",
361///         "0.50000#10",
362///         "4.0000#10",
363///         "0.50098#10",
364///         "4.0078#10",
365///         "1.0039#10",
366///         "2.0078#10",
367///         "1.0059#10",
368///         "2.0117#10",
369///         "0.50195#10",
370///         "4.0156#10",
371///         "0.50293#10",
372///         "4.0234#10",
373///         "0.25000#10",
374///         "8.0000#10",
375///         "0.25049#10",
376///         "8.0156#10"
377///     ]
378/// );
379/// ```
380#[inline]
381pub fn exhaustive_positive_floats_with_precision(
382    prec: u64,
383) -> ExhaustivePositiveFloatsWithPrecision {
384    assert_ne!(prec, 0);
385    ExhaustivePositiveFloatsWithPrecision(exhaustive_floats_with_precision_helper(prec))
386}
387
388/// Generates all [`Float`]s with a specified precision. (Since they have a precision, they are
389/// finite and nonzero.)
390///
391/// This `struct` is created by [`exhaustive_floats_with_precision`]; see its documentation for
392/// more.
393#[derive(Clone, Debug)]
394pub struct ExhaustiveFloatsWithPrecision {
395    toggle: bool,
396    xs: ExhaustivePositiveFloatsWithPrecision,
397    x: Float,
398}
399
400impl Iterator for ExhaustiveFloatsWithPrecision {
401    type Item = Float;
402
403    #[inline]
404    fn next(&mut self) -> Option<Float> {
405        self.toggle.not_assign();
406        Some(if self.toggle {
407            self.x = self.xs.next().unwrap();
408            self.x.clone()
409        } else {
410            let mut out = Float::NAN;
411            swap(&mut out, &mut self.x);
412            -out
413        })
414    }
415}
416
417/// Generates all [`Float`]s with a specified precision. (Since they have a precision, they are
418/// finite and nonzero.)
419///
420/// # Worst-case complexity per iteration
421/// $T(i) = O(\log i)$
422///
423/// $M(i) = O(\log i)$
424///
425/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
426///
427/// # Panics
428/// Panics if the precision is zero.
429///
430/// ```
431/// use itertools::Itertools;
432/// use malachite_float::float::exhaustive::exhaustive_floats_with_precision;
433/// use malachite_float::ComparableFloat;
434///
435/// // The number after the '#' is the precision.
436/// assert_eq!(
437///     exhaustive_floats_with_precision(1)
438///         .take(20)
439///         .map(|f| ComparableFloat(f).to_string())
440///         .collect_vec()
441///         .as_slice(),
442///     &[
443///         "1.0#1", "-1.0#1", "2.0#1", "-2.0#1", "0.50#1", "-0.50#1", "4.0#1", "-4.0#1", "0.25#1",
444///         "-0.25#1", "8.0#1", "-8.0#1", "0.12#1", "-0.12#1", "16.0#1", "-16.0#1", "0.062#1",
445///         "-0.062#1", "32.0#1", "-32.0#1"
446///     ]
447/// );
448///
449/// assert_eq!(
450///     exhaustive_floats_with_precision(10)
451///         .take(20)
452///         .map(|f| ComparableFloat(f).to_string())
453///         .collect_vec()
454///         .as_slice(),
455///     &[
456///         "1.0000#10",
457///         "-1.0000#10",
458///         "2.0000#10",
459///         "-2.0000#10",
460///         "1.0020#10",
461///         "-1.0020#10",
462///         "2.0039#10",
463///         "-2.0039#10",
464///         "0.50000#10",
465///         "-0.50000#10",
466///         "4.0000#10",
467///         "-4.0000#10",
468///         "0.50098#10",
469///         "-0.50098#10",
470///         "4.0078#10",
471///         "-4.0078#10",
472///         "1.0039#10",
473///         "-1.0039#10",
474///         "2.0078#10",
475///         "-2.0078#10"
476///     ]
477/// );
478/// ```
479#[inline]
480pub fn exhaustive_floats_with_precision(prec: u64) -> ExhaustiveFloatsWithPrecision {
481    ExhaustiveFloatsWithPrecision {
482        toggle: false,
483        xs: exhaustive_positive_floats_with_precision(prec),
484        x: Float::NAN,
485    }
486}
487
488#[derive(Clone, Debug)]
489pub(crate) struct ExhaustivePositiveFiniteFloatsGenerator;
490
491impl ExhaustiveDependentPairsYsGenerator<i32, Float, ExhaustivePositiveFloatsWithSciExponent>
492    for ExhaustivePositiveFiniteFloatsGenerator
493{
494    #[inline]
495    fn get_ys(&self, &sci_exponent: &i32) -> ExhaustivePositiveFloatsWithSciExponent {
496        exhaustive_positive_floats_with_sci_exponent(sci_exponent)
497    }
498}
499
500#[inline]
501fn exhaustive_positive_finite_floats_helper() -> ExhaustiveDependentPairs<
502    i32,
503    Float,
504    BitDistributorSequence,
505    ExhaustivePositiveFiniteFloatsGenerator,
506    ExhaustiveSignedRange<i32>,
507    ExhaustivePositiveFloatsWithSciExponent,
508> {
509    exhaustive_dependent_pairs(
510        bit_distributor_sequence(
511            BitDistributorOutputType::normal(1),
512            BitDistributorOutputType::normal(1),
513        ),
514        exhaustive_signed_inclusive_range(Float::MIN_EXPONENT, Float::MAX_EXPONENT),
515        ExhaustivePositiveFiniteFloatsGenerator,
516    )
517}
518
519/// Generates all positive finite [`Float`]s.
520///
521/// This `struct` is created by [`exhaustive_positive_finite_floats`]; see its documentation for
522/// more.
523#[derive(Clone, Debug)]
524pub struct ExhaustivePositiveFiniteFloats(
525    ExhaustiveDependentPairs<
526        i32,
527        Float,
528        BitDistributorSequence,
529        ExhaustivePositiveFiniteFloatsGenerator,
530        ExhaustiveSignedRange<i32>,
531        ExhaustivePositiveFloatsWithSciExponent,
532    >,
533);
534
535impl Iterator for ExhaustivePositiveFiniteFloats {
536    type Item = Float;
537
538    #[inline]
539    fn next(&mut self) -> Option<Float> {
540        self.0.next().map(|p| p.1)
541    }
542}
543
544/// Generates all positive finite [`Float`]s.
545///
546/// Positive and negative zero are both excluded.
547///
548/// # Worst-case complexity per iteration
549/// $T(i) = O(\log i)$
550///
551/// $M(i) = O(\log i)$
552///
553/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
554///
555/// ```
556/// use itertools::Itertools;
557/// use malachite_float::float::exhaustive::exhaustive_positive_finite_floats;
558/// use malachite_float::ComparableFloat;
559///
560/// // The number after the '#' is the precision.
561/// assert_eq!(
562///     exhaustive_positive_finite_floats()
563///         .take(20)
564///         .map(|f| ComparableFloat(f).to_string())
565///         .collect_vec()
566///         .as_slice(),
567///     &[
568///         "1.0#1", "2.0#1", "1.0#2", "2.0#2", "0.50#1", "4.0#1", "0.50#2", "4.0#2", "1.5#2",
569///         "3.0#2", "1.0#3", "2.0#3", "0.75#2", "6.0#2", "0.50#3", "4.0#3", "0.25#1", "8.0#1",
570///         "0.25#2", "8.0#2"
571///     ]
572/// );
573/// ```
574#[inline]
575pub fn exhaustive_positive_finite_floats() -> ExhaustivePositiveFiniteFloats {
576    ExhaustivePositiveFiniteFloats(exhaustive_positive_finite_floats_helper())
577}
578
579/// Generates all negative finite [`Float`]s.
580///
581/// This `struct` is created by [`exhaustive_negative_finite_floats`]; see its documentation for
582/// more.
583#[derive(Clone, Debug)]
584pub struct ExhaustiveNegativeFiniteFloats(ExhaustivePositiveFiniteFloats);
585
586impl Iterator for ExhaustiveNegativeFiniteFloats {
587    type Item = Float;
588
589    #[inline]
590    fn next(&mut self) -> Option<Float> {
591        self.0.next().map(|f| -f)
592    }
593}
594
595/// Generates all negative finite [`Float`]s.
596///
597/// Positive and negative zero are both excluded.
598///
599/// # Worst-case complexity per iteration
600/// $T(i) = O(\log i)$
601///
602/// $M(i) = O(\log i)$
603///
604/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
605///
606/// ```
607/// use itertools::Itertools;
608/// use malachite_float::float::exhaustive::exhaustive_negative_finite_floats;
609/// use malachite_float::ComparableFloat;
610///
611/// // The number after the '#' is the precision.
612/// assert_eq!(
613///     exhaustive_negative_finite_floats()
614///         .take(20)
615///         .map(|f| ComparableFloat(f).to_string())
616///         .collect_vec()
617///         .as_slice(),
618///     &[
619///         "-1.0#1", "-2.0#1", "-1.0#2", "-2.0#2", "-0.50#1", "-4.0#1", "-0.50#2", "-4.0#2",
620///         "-1.5#2", "-3.0#2", "-1.0#3", "-2.0#3", "-0.75#2", "-6.0#2", "-0.50#3", "-4.0#3",
621///         "-0.25#1", "-8.0#1", "-0.25#2", "-8.0#2"
622///     ]
623/// );
624/// ```
625#[inline]
626pub fn exhaustive_negative_finite_floats() -> ExhaustiveNegativeFiniteFloats {
627    ExhaustiveNegativeFiniteFloats(exhaustive_positive_finite_floats())
628}
629
630/// Generates all nonzero finite [`Float`]s.
631///
632/// This `struct` is created by [`exhaustive_nonzero_finite_floats`]; see its documentation for
633/// more.
634#[derive(Clone, Debug)]
635pub struct ExhaustiveNonzeroFiniteFloats {
636    toggle: bool,
637    xs: ExhaustivePositiveFiniteFloats,
638    x: Float,
639}
640
641impl Iterator for ExhaustiveNonzeroFiniteFloats {
642    type Item = Float;
643
644    #[inline]
645    fn next(&mut self) -> Option<Float> {
646        self.toggle.not_assign();
647        Some(if self.toggle {
648            self.x = self.xs.next().unwrap();
649            self.x.clone()
650        } else {
651            let mut out = Float::NAN;
652            swap(&mut out, &mut self.x);
653            -out
654        })
655    }
656}
657
658/// Generates all nonzero finite [`Float`]s.
659///
660/// Positive and negative zero are both excluded.
661///
662/// # Worst-case complexity per iteration
663/// $T(i) = O(\log i)$
664///
665/// $M(i) = O(\log i)$
666///
667/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
668///
669/// ```
670/// use itertools::Itertools;
671/// use malachite_float::float::exhaustive::exhaustive_nonzero_finite_floats;
672/// use malachite_float::ComparableFloat;
673///
674/// // The number after the '#' is the precision.
675/// assert_eq!(
676///     exhaustive_nonzero_finite_floats()
677///         .take(20)
678///         .map(|f| ComparableFloat(f).to_string())
679///         .collect_vec()
680///         .as_slice(),
681///     &[
682///         "1.0#1", "-1.0#1", "2.0#1", "-2.0#1", "1.0#2", "-1.0#2", "2.0#2", "-2.0#2", "0.50#1",
683///         "-0.50#1", "4.0#1", "-4.0#1", "0.50#2", "-0.50#2", "4.0#2", "-4.0#2", "1.5#2",
684///         "-1.5#2", "3.0#2", "-3.0#2"
685///     ]
686/// );
687/// ```
688#[inline]
689pub fn exhaustive_nonzero_finite_floats() -> ExhaustiveNonzeroFiniteFloats {
690    ExhaustiveNonzeroFiniteFloats {
691        toggle: false,
692        xs: exhaustive_positive_finite_floats(),
693        x: Float::NAN,
694    }
695}
696
697type ExhaustiveNonNegativeFiniteFloats = Chain<Once<Float>, ExhaustivePositiveFiniteFloats>;
698
699/// Generates all non-negative finite [`Float`]s.
700///
701/// Positive zero is included, but negative zero is not.
702///
703/// # Worst-case complexity per iteration
704/// $T(i) = O(\log i)$
705///
706/// $M(i) = O(\log i)$
707///
708/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
709///
710/// ```
711/// use itertools::Itertools;
712/// use malachite_float::float::exhaustive::exhaustive_non_negative_finite_floats;
713/// use malachite_float::ComparableFloat;
714///
715/// // The number after the '#' is the precision.
716/// assert_eq!(
717///     exhaustive_non_negative_finite_floats()
718///         .take(20)
719///         .map(|f| ComparableFloat(f).to_string())
720///         .collect_vec()
721///         .as_slice(),
722///     &[
723///         "0.0", "1.0#1", "2.0#1", "1.0#2", "2.0#2", "0.50#1", "4.0#1", "0.50#2", "4.0#2",
724///         "1.5#2", "3.0#2", "1.0#3", "2.0#3", "0.75#2", "6.0#2", "0.50#3", "4.0#3", "0.25#1",
725///         "8.0#1", "0.25#2"
726///     ]
727/// );
728/// ```
729#[inline]
730pub fn exhaustive_non_negative_finite_floats() -> ExhaustiveNonNegativeFiniteFloats {
731    once(Float::ZERO).chain(exhaustive_positive_finite_floats())
732}
733
734type ExhaustiveNonPositiveFiniteFloats = Chain<Once<Float>, ExhaustiveNegativeFiniteFloats>;
735
736/// Generates all non-positive finite [`Float`]s.
737///
738/// Negative zero is included, but positive zero is not.
739///
740/// # Worst-case complexity per iteration
741/// $T(i) = O(\log i)$
742///
743/// $M(i) = O(\log i)$
744///
745/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
746///
747/// ```
748/// use itertools::Itertools;
749/// use malachite_float::float::exhaustive::exhaustive_non_positive_finite_floats;
750/// use malachite_float::ComparableFloat;
751///
752/// // The number after the '#' is the precision.
753/// assert_eq!(
754///     exhaustive_non_positive_finite_floats()
755///         .take(20)
756///         .map(|f| ComparableFloat(f).to_string())
757///         .collect_vec()
758///         .as_slice(),
759///     &[
760///         "-0.0", "-1.0#1", "-2.0#1", "-1.0#2", "-2.0#2", "-0.50#1", "-4.0#1", "-0.50#2",
761///         "-4.0#2", "-1.5#2", "-3.0#2", "-1.0#3", "-2.0#3", "-0.75#2", "-6.0#2", "-0.50#3",
762///         "-4.0#3", "-0.25#1", "-8.0#1", "-0.25#2"
763///     ]
764/// );
765/// ```
766#[inline]
767pub fn exhaustive_non_positive_finite_floats() -> ExhaustiveNonPositiveFiniteFloats {
768    once(Float::NEGATIVE_ZERO).chain(exhaustive_negative_finite_floats())
769}
770
771type ExhaustiveFloats = Chain<IntoIter<Float>, ExhaustiveNonzeroFiniteFloats>;
772
773/// Generates all finite [`Float`]s.
774///
775/// # Worst-case complexity per iteration
776/// $T(i) = O(\log i)$
777///
778/// $M(i) = O(\log i)$
779///
780/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
781///
782/// ```
783/// use itertools::Itertools;
784/// use malachite_float::float::exhaustive::exhaustive_finite_floats;
785/// use malachite_float::ComparableFloat;
786///
787/// // The number after the '#' is the precision.
788/// assert_eq!(
789///     exhaustive_finite_floats()
790///         .take(20)
791///         .map(|f| ComparableFloat(f).to_string())
792///         .collect_vec()
793///         .as_slice(),
794///     &[
795///         "0.0", "-0.0", "1.0#1", "-1.0#1", "2.0#1", "-2.0#1", "1.0#2", "-1.0#2", "2.0#2",
796///         "-2.0#2", "0.50#1", "-0.50#1", "4.0#1", "-4.0#1", "0.50#2", "-0.50#2", "4.0#2",
797///         "-4.0#2", "1.5#2", "-1.5#2"
798///     ]
799/// );
800/// ```
801#[inline]
802pub fn exhaustive_finite_floats() -> ExhaustiveFloats {
803    alloc::vec![Float::ZERO, Float::NEGATIVE_ZERO]
804        .into_iter()
805        .chain(exhaustive_nonzero_finite_floats())
806}
807
808/// Generates all [`Float`]s.
809///
810/// # Worst-case complexity per iteration
811/// $T(i) = O(\log i)$
812///
813/// $M(i) = O(\log i)$
814///
815/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
816///
817/// ```
818/// use itertools::Itertools;
819/// use malachite_float::float::exhaustive::exhaustive_floats;
820/// use malachite_float::ComparableFloat;
821///
822/// // The number after the '#' is the precision.
823/// assert_eq!(
824///     exhaustive_floats()
825///         .take(50)
826///         .map(|f| ComparableFloat(f).to_string())
827///         .collect_vec()
828///         .as_slice(),
829///     &[
830///         "NaN",
831///         "Infinity",
832///         "-Infinity",
833///         "0.0",
834///         "-0.0",
835///         "1.0#1",
836///         "-1.0#1",
837///         "2.0#1",
838///         "-2.0#1",
839///         "1.0#2",
840///         "-1.0#2",
841///         "2.0#2",
842///         "-2.0#2",
843///         "0.50#1",
844///         "-0.50#1",
845///         "4.0#1",
846///         "-4.0#1",
847///         "0.50#2",
848///         "-0.50#2",
849///         "4.0#2",
850///         "-4.0#2",
851///         "1.5#2",
852///         "-1.5#2",
853///         "3.0#2",
854///         "-3.0#2",
855///         "1.0#3",
856///         "-1.0#3",
857///         "2.0#3",
858///         "-2.0#3",
859///         "0.75#2",
860///         "-0.75#2",
861///         "6.0#2",
862///         "-6.0#2",
863///         "0.50#3",
864///         "-0.50#3",
865///         "4.0#3",
866///         "-4.0#3",
867///         "0.25#1",
868///         "-0.25#1",
869///         "8.0#1",
870///         "-8.0#1",
871///         "0.25#2",
872///         "-0.25#2",
873///         "8.0#2",
874///         "-8.0#2",
875///         "0.12#1",
876///         "-0.12#1",
877///         "16.0#1",
878///         "-16.0#1",
879///         "0.12#2"
880///     ]
881/// );
882/// ```
883#[inline]
884pub fn exhaustive_floats() -> ExhaustiveFloats {
885    alloc::vec![
886        Float::NAN,
887        Float::INFINITY,
888        Float::NEGATIVE_INFINITY,
889        Float::ZERO,
890        Float::NEGATIVE_ZERO
891    ]
892    .into_iter()
893    .chain(exhaustive_nonzero_finite_floats())
894}