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}