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