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}