malachite_base/num/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::iterators::{NonzeroValues, nonzero_values};
10use crate::num::arithmetic::traits::{PowerOf2, RoundToMultipleOfPowerOf2};
11use crate::num::basic::floats::PrimitiveFloat;
12use crate::num::basic::integers::PrimitiveInt;
13use crate::num::basic::signeds::PrimitiveSigned;
14use crate::num::basic::unsigneds::PrimitiveUnsigned;
15use crate::num::conversion::traits::{ExactFrom, WrappingFrom};
16use crate::num::float::NiceFloat;
17use crate::num::iterators::{RulerSequence, ruler_sequence};
18use crate::num::logic::traits::{BitAccess, NotAssign, SignificantBits};
19use crate::rounding_modes::RoundingMode::*;
20use crate::tuples::exhaustive::{
21 ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, LexDependentPairs,
22 exhaustive_dependent_pairs, lex_dependent_pairs,
23};
24use alloc::vec::IntoIter;
25use alloc::vec::Vec;
26use core::iter::{Chain, Once, Rev, once};
27use core::marker::PhantomData;
28use itertools::{Interleave, Itertools};
29
30/// Generates all primitive integers in an interval.
31///
32/// This `struct` is created by [`primitive_int_increasing_range`] and
33/// [`primitive_int_increasing_inclusive_range`]; see their documentation for more.
34#[derive(Clone, Debug, Eq, Hash, PartialEq)]
35pub struct PrimitiveIntIncreasingRange<T: PrimitiveInt> {
36 a: Option<T>,
37 b: Option<T>,
38}
39
40impl<T: PrimitiveInt> Iterator for PrimitiveIntIncreasingRange<T> {
41 type Item = T;
42
43 fn next(&mut self) -> Option<T> {
44 if self.a == self.b {
45 None
46 } else {
47 let result = self.a;
48 self.a = result.and_then(|x| x.checked_add(T::ONE));
49 result
50 }
51 }
52}
53
54impl<T: PrimitiveInt> DoubleEndedIterator for PrimitiveIntIncreasingRange<T> {
55 fn next_back(&mut self) -> Option<T> {
56 if self.a == self.b {
57 None
58 } else {
59 self.b = Some(self.b.map_or(T::MAX, |b| b - T::ONE));
60 self.b
61 }
62 }
63}
64
65/// Generates all values of a signed integer type in an interval, in order of increasing absolute
66/// value.
67///
68/// This `enum` is created by [`exhaustive_signed_range`] and [`exhaustive_signed_inclusive_range`];
69/// see their documentation for more.
70#[derive(Clone, Debug)]
71pub enum ExhaustiveSignedRange<T: PrimitiveSigned> {
72 NonNegative(PrimitiveIntIncreasingRange<T>),
73 NonPositive(Rev<PrimitiveIntIncreasingRange<T>>),
74 BothSigns(ExhaustiveSigneds<T>),
75}
76
77impl<T: PrimitiveSigned> Iterator for ExhaustiveSignedRange<T> {
78 type Item = T;
79
80 fn next(&mut self) -> Option<T> {
81 match self {
82 Self::NonNegative(xs) => xs.next(),
83 Self::NonPositive(xs) => xs.next(),
84 Self::BothSigns(xs) => xs.next(),
85 }
86 }
87}
88
89#[doc(hidden)]
90pub type PrimitiveIntUpDown<T> =
91 Interleave<PrimitiveIntIncreasingRange<T>, Rev<PrimitiveIntIncreasingRange<T>>>;
92
93/// Generates all unsigned integers in ascending order.
94///
95/// The output is $(k)_{k=0}^{2^W-1}$, where $W$ is the width of the type.
96///
97/// The output length is $2^W$.
98///
99/// # Complexity per iteration
100/// Constant time and additional memory.
101///
102/// # Examples
103/// ```
104/// use malachite_base::iterators::prefix_to_string;
105/// use malachite_base::num::exhaustive::exhaustive_unsigneds;
106///
107/// assert_eq!(
108/// prefix_to_string(exhaustive_unsigneds::<u8>(), 10),
109/// "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]"
110/// )
111/// ```
112#[inline]
113pub fn exhaustive_unsigneds<T: PrimitiveUnsigned>() -> PrimitiveIntIncreasingRange<T> {
114 primitive_int_increasing_inclusive_range(T::ZERO, T::MAX)
115}
116
117/// Generates all positive primitive integers in ascending order.
118///
119/// Let $L=2^W-1$ if `T` is unsigned and $L=2^{W-1}-1$ if `T` is signed, where $W$ is the width of
120/// the type.
121///
122/// The output is $(k)_{k=1}^{L}$.
123///
124/// The output length is $L$.
125///
126/// # Complexity per iteration
127/// Constant time and additional memory.
128///
129/// # Examples
130/// ```
131/// use malachite_base::iterators::prefix_to_string;
132/// use malachite_base::num::exhaustive::exhaustive_positive_primitive_ints;
133///
134/// assert_eq!(
135/// prefix_to_string(exhaustive_positive_primitive_ints::<u8>(), 10),
136/// "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]"
137/// )
138/// ```
139#[inline]
140pub fn exhaustive_positive_primitive_ints<T: PrimitiveInt>() -> PrimitiveIntIncreasingRange<T> {
141 primitive_int_increasing_inclusive_range(T::ONE, T::MAX)
142}
143
144pub type ExhaustiveSigneds<T> = Chain<Once<T>, PrimitiveIntUpDown<T>>;
145
146/// Generates all signed integers in order of increasing absolute value.
147///
148/// When two numbers have the same absolute value, the positive one comes first.
149///
150/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
151/// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [-2^{W-1}, 2^{W-1})$, where $W$ is the width of
152/// the type, and $i < j$.
153///
154/// The output length is $2^W$.
155///
156/// # Complexity per iteration
157/// Constant time and additional memory.
158///
159/// # Examples
160/// ```
161/// use malachite_base::iterators::prefix_to_string;
162/// use malachite_base::num::exhaustive::exhaustive_signeds;
163///
164/// assert_eq!(
165/// prefix_to_string(exhaustive_signeds::<i8>(), 10),
166/// "[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, ...]"
167/// )
168/// ```
169#[inline]
170pub fn exhaustive_signeds<T: PrimitiveSigned>() -> ExhaustiveSigneds<T> {
171 once(T::ZERO).chain(exhaustive_nonzero_signeds())
172}
173
174/// Generates all natural (non-negative) signed integers in ascending order.
175///
176/// The output is $(k)_{k=0}^{2^{W-1}-1}$, where $W$ is the width of the type.
177///
178/// The output length is $2^{W-1}$.
179///
180/// # Complexity per iteration
181/// Constant time and additional memory.
182///
183/// # Examples
184/// ```
185/// use malachite_base::iterators::prefix_to_string;
186/// use malachite_base::num::exhaustive::exhaustive_natural_signeds;
187///
188/// assert_eq!(
189/// prefix_to_string(exhaustive_natural_signeds::<i8>(), 10),
190/// "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]"
191/// )
192/// ```
193#[inline]
194pub fn exhaustive_natural_signeds<T: PrimitiveSigned>() -> PrimitiveIntIncreasingRange<T> {
195 primitive_int_increasing_inclusive_range(T::ZERO, T::MAX)
196}
197
198/// Generates all negative signed integers in descending order.
199///
200/// The output is $(-k)_{k=1}^{2^{W-1}}$, where $W$ is the width of the type.
201///
202/// The output length is $2^{W-1}$.
203///
204/// # Complexity per iteration
205/// Constant time and additional memory.
206///
207/// # Examples
208/// ```
209/// use malachite_base::iterators::prefix_to_string;
210/// use malachite_base::num::exhaustive::exhaustive_negative_signeds;
211///
212/// assert_eq!(
213/// prefix_to_string(exhaustive_negative_signeds::<i8>(), 10),
214/// "[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, ...]"
215/// )
216/// ```
217#[inline]
218pub fn exhaustive_negative_signeds<T: PrimitiveSigned>() -> Rev<PrimitiveIntIncreasingRange<T>> {
219 primitive_int_increasing_range(T::MIN, T::ZERO).rev()
220}
221
222/// Generates all nonzero signed integers in order of increasing absolute value.
223///
224/// When two numbers have the same absolute value, the positive one comes first.
225///
226/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
227/// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [-2^{W-1}, 2^{W-1}) \\setminus \\{0\\}$, where
228/// $W$ is the width of the type, and $i < j$.
229///
230/// The output length is $2^W-1$.
231///
232/// # Complexity per iteration
233/// Constant time and additional memory.
234///
235/// # Examples
236/// ```
237/// use malachite_base::iterators::prefix_to_string;
238/// use malachite_base::num::exhaustive::exhaustive_nonzero_signeds;
239///
240/// assert_eq!(
241/// prefix_to_string(exhaustive_nonzero_signeds::<i8>(), 10),
242/// "[1, -1, 2, -2, 3, -3, 4, -4, 5, -5, ...]"
243/// )
244/// ```
245#[inline]
246pub fn exhaustive_nonzero_signeds<T: PrimitiveSigned>() -> PrimitiveIntUpDown<T> {
247 exhaustive_positive_primitive_ints().interleave(exhaustive_negative_signeds())
248}
249
250/// Generates all primitive integers in the half-open interval $[a, b)$, in ascending order.
251///
252/// $a$ must be less than or equal to $b$. If $a$ and $b$ are equal, the range is empty. This
253/// function cannot create a range that includes `T::MAX`; for that, use
254/// [`primitive_int_increasing_inclusive_range`].
255///
256/// The output is $(k)_{k=a}^{b-1}$.
257///
258/// The output length is $b - a$.
259///
260/// # Complexity per iteration
261/// Constant time and additional memory.
262///
263/// # Panics
264/// Panics if $a > b$.
265///
266/// # Examples
267/// ```
268/// use itertools::Itertools;
269/// use malachite_base::num::exhaustive::primitive_int_increasing_range;
270///
271/// assert_eq!(
272/// primitive_int_increasing_range::<i8>(-5, 5).collect_vec(),
273/// &[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
274/// )
275/// ```
276#[inline]
277pub fn primitive_int_increasing_range<T: PrimitiveInt>(
278 a: T,
279 b: T,
280) -> PrimitiveIntIncreasingRange<T> {
281 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
282 PrimitiveIntIncreasingRange {
283 a: Some(a),
284 b: Some(b),
285 }
286}
287
288/// Generates all primitive integers in the closed interval $[a, b]$, in ascending order.
289///
290/// $a$ must be less than or equal to $b$. If $a$ and $b$ are equal, the range contains a single
291/// element.
292///
293/// The output is $(k)_{k=a}^{b}$.
294///
295/// The output length is $b - a + 1$.
296///
297/// # Complexity per iteration
298/// Constant time and additional memory.
299///
300/// # Panics
301/// Panics if $a > b$.
302///
303/// # Examples
304/// ```
305/// use itertools::Itertools;
306/// use malachite_base::num::exhaustive::primitive_int_increasing_inclusive_range;
307///
308/// assert_eq!(
309/// primitive_int_increasing_inclusive_range::<i8>(-5, 5).collect_vec(),
310/// &[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
311/// )
312/// ```
313#[inline]
314pub fn primitive_int_increasing_inclusive_range<T: PrimitiveInt>(
315 a: T,
316 b: T,
317) -> PrimitiveIntIncreasingRange<T> {
318 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
319 PrimitiveIntIncreasingRange {
320 a: Some(a),
321 b: b.checked_add(T::ONE),
322 }
323}
324
325/// Generates all signed integers in the half-open interval $[a, b)$, in order of increasing
326/// absolute value.
327///
328/// When two numbers have the same absolute value, the positive one comes first. $a$ must be less
329/// than or equal to $b$. If $a$ and $b$ are equal, the range is empty. This function cannot create
330/// a range that includes `T::MAX`; for that, use [`exhaustive_signed_inclusive_range`].
331///
332/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
333/// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [0, b - a)$ and $i < j$.
334///
335/// The output length is $b - a$.
336///
337/// # Complexity per iteration
338/// Constant time and additional memory.
339///
340/// # Panics
341/// Panics if $a > b$.
342///
343/// # Examples
344/// ```
345/// use itertools::Itertools;
346/// use malachite_base::num::exhaustive::exhaustive_signed_range;
347///
348/// assert_eq!(
349/// exhaustive_signed_range::<i8>(-5, 5).collect_vec(),
350/// &[0, 1, -1, 2, -2, 3, -3, 4, -4, -5]
351/// )
352/// ```
353pub fn exhaustive_signed_range<T: PrimitiveSigned>(a: T, b: T) -> ExhaustiveSignedRange<T> {
354 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
355 if a >= T::ZERO {
356 ExhaustiveSignedRange::NonNegative(primitive_int_increasing_range(a, b))
357 } else if b <= T::ZERO {
358 ExhaustiveSignedRange::NonPositive(primitive_int_increasing_range(a, b).rev())
359 } else {
360 ExhaustiveSignedRange::BothSigns(
361 once(T::ZERO).chain(
362 primitive_int_increasing_range(T::ONE, b)
363 .interleave(primitive_int_increasing_range(a, T::ZERO).rev()),
364 ),
365 )
366 }
367}
368
369/// Generates all signed integers in the closed interval $[a, b]$, in order of increasing absolute
370/// value.
371///
372/// When two numbers have the same absolute value, the positive one comes first. $a$ must be less
373/// than or equal to $b$. If $a$ and $b$ are equal, the range contains a single element.
374///
375/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
376/// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [0, b - a]$ and $i < j$.
377///
378/// The output length is $b - a + 1$.
379///
380/// # Complexity per iteration
381/// Constant time and additional memory.
382///
383/// # Panics
384/// Panics if $a > b$.
385///
386/// # Examples
387/// ```
388/// use itertools::Itertools;
389/// use malachite_base::num::exhaustive::exhaustive_signed_inclusive_range;
390///
391/// assert_eq!(
392/// exhaustive_signed_inclusive_range::<i8>(-5, 5).collect_vec(),
393/// &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5]
394/// )
395/// ```
396pub fn exhaustive_signed_inclusive_range<T: PrimitiveSigned>(
397 a: T,
398 b: T,
399) -> ExhaustiveSignedRange<T> {
400 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
401 if a >= T::ZERO {
402 ExhaustiveSignedRange::NonNegative(primitive_int_increasing_inclusive_range(a, b))
403 } else if b <= T::ZERO {
404 ExhaustiveSignedRange::NonPositive(primitive_int_increasing_inclusive_range(a, b).rev())
405 } else {
406 ExhaustiveSignedRange::BothSigns(
407 once(T::ZERO).chain(
408 primitive_int_increasing_inclusive_range(T::ONE, b)
409 .interleave(primitive_int_increasing_inclusive_range(a, T::NEGATIVE_ONE).rev()),
410 ),
411 )
412 }
413}
414
415/// Generates all primitive floats in an interval, in increasing order.
416///
417/// This `struct` implements [`DoubleEndedIterator`], so you can reverse it to generate floats in
418/// decreasing order.
419///
420/// Positive zero and negative zero are both generated. Negative zero is considered to be less than
421/// positive zero.
422///
423/// This `struct` is created by [`primitive_float_increasing_range`] and
424/// [`primitive_float_increasing_inclusive_range`]; see their documentation for more.
425#[derive(Clone, Debug, Eq, Hash, PartialEq)]
426pub struct PrimitiveFloatIncreasingRange<T: PrimitiveFloat> {
427 phantom: PhantomData<*const T>,
428 xs: PrimitiveIntIncreasingRange<u64>,
429}
430
431impl<T: PrimitiveFloat> Iterator for PrimitiveFloatIncreasingRange<T> {
432 type Item = T;
433
434 #[inline]
435 fn next(&mut self) -> Option<T> {
436 self.xs.next().map(T::from_ordered_representation)
437 }
438}
439
440impl<T: PrimitiveFloat> DoubleEndedIterator for PrimitiveFloatIncreasingRange<T> {
441 #[inline]
442 fn next_back(&mut self) -> Option<T> {
443 self.xs.next_back().map(T::from_ordered_representation)
444 }
445}
446
447/// Generates all primitive floats in the half-open interval $[a, b)$, in ascending order.
448///
449/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
450/// than zero.
451///
452/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
453/// `NiceFloat(b)` are equal, the range is empty. This function cannot create a range that includes
454/// `INFINITY`; for that, use [`primitive_float_increasing_inclusive_range`].
455///
456/// Let $\varphi$ be
457/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
458///
459/// The output is $(\varphi^{-1}(k))_{k=\varphi(a)}^{\varphi(b)-1}$.
460///
461/// The output length is $\varphi(b) - \varphi(a)$.
462///
463/// # Complexity per iteration
464/// Constant time and additional memory.
465///
466/// # Panics
467/// Panics if `NiceFloat(a) > NiceFloat(b)`.
468///
469/// # Examples
470/// ```
471/// use malachite_base::iterators::prefix_to_string;
472/// use malachite_base::num::exhaustive::primitive_float_increasing_range;
473/// use malachite_base::num::float::NiceFloat;
474///
475/// assert_eq!(
476/// prefix_to_string(
477/// primitive_float_increasing_range::<f32>(1.0, 2.0).map(NiceFloat),
478/// 20
479/// ),
480/// "[1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, \
481/// 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, \
482/// 1.0000019, 1.000002, 1.0000021, 1.0000023, ...]"
483/// );
484/// assert_eq!(
485/// prefix_to_string(
486/// primitive_float_increasing_range::<f32>(1.0, 2.0)
487/// .rev()
488/// .map(NiceFloat),
489/// 20,
490/// ),
491/// "[1.9999999, 1.9999998, 1.9999996, 1.9999995, 1.9999994, 1.9999993, 1.9999992, 1.999999, \
492/// 1.9999989, 1.9999988, 1.9999987, 1.9999986, 1.9999985, 1.9999983, 1.9999982, 1.9999981, \
493/// 1.999998, 1.9999979, 1.9999977, 1.9999976, ...]",
494/// );
495/// ```
496pub fn primitive_float_increasing_range<T: PrimitiveFloat>(
497 a: T,
498 b: T,
499) -> PrimitiveFloatIncreasingRange<T> {
500 assert!(!a.is_nan());
501 assert!(!b.is_nan());
502 assert!(
503 NiceFloat(a) <= NiceFloat(b),
504 "a must be less than or equal to b. a: {}, b: {}",
505 NiceFloat(a),
506 NiceFloat(b)
507 );
508 PrimitiveFloatIncreasingRange {
509 phantom: PhantomData,
510 xs: primitive_int_increasing_range(
511 a.to_ordered_representation(),
512 b.to_ordered_representation(),
513 ),
514 }
515}
516
517/// Generates all primitive floats in the closed interval $[a, b]$, in ascending order.
518///
519/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
520/// than zero.
521///
522/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
523/// `NiceFloat(b)` are equal, the range contains a single element.
524///
525/// Let $\varphi$ be
526/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
527///
528/// The output is $(\varphi^{-1}(k))_{k=\varphi(a)}^\varphi(b)$.
529///
530/// The output length is $\varphi(b) - \varphi(a) + 1$.
531///
532/// # Complexity per iteration
533/// Constant time and additional memory.
534///
535/// # Panics
536/// Panics if `NiceFloat(a) > NiceFloat(b)`.
537///
538/// # Examples
539/// ```
540/// use malachite_base::iterators::prefix_to_string;
541/// use malachite_base::num::exhaustive::primitive_float_increasing_inclusive_range;
542/// use malachite_base::num::float::NiceFloat;
543///
544/// assert_eq!(
545/// prefix_to_string(
546/// primitive_float_increasing_inclusive_range::<f32>(1.0, 2.0).map(NiceFloat),
547/// 20
548/// ),
549/// "[1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, \
550/// 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, \
551/// 1.0000019, 1.000002, 1.0000021, 1.0000023, ...]"
552/// );
553/// assert_eq!(
554/// prefix_to_string(
555/// primitive_float_increasing_inclusive_range::<f32>(1.0, 2.0)
556/// .rev()
557/// .map(NiceFloat),
558/// 20
559/// ),
560/// "[2.0, 1.9999999, 1.9999998, 1.9999996, 1.9999995, 1.9999994, 1.9999993, 1.9999992, \
561/// 1.999999, 1.9999989, 1.9999988, 1.9999987, 1.9999986, 1.9999985, 1.9999983, 1.9999982, \
562/// 1.9999981, 1.999998, 1.9999979, 1.9999977, ...]"
563/// );
564/// ```
565pub fn primitive_float_increasing_inclusive_range<T: PrimitiveFloat>(
566 a: T,
567 b: T,
568) -> PrimitiveFloatIncreasingRange<T> {
569 assert!(!a.is_nan());
570 assert!(!b.is_nan());
571 assert!(
572 NiceFloat(a) <= NiceFloat(b),
573 "a must be less than or equal to b. a: {}, b: {}",
574 NiceFloat(a),
575 NiceFloat(b)
576 );
577 PrimitiveFloatIncreasingRange {
578 phantom: PhantomData,
579 xs: primitive_int_increasing_inclusive_range(
580 a.to_ordered_representation(),
581 b.to_ordered_representation(),
582 ),
583 }
584}
585
586/// Generates all finite positive primitive floats, in ascending order.
587///
588/// Positive and negative zero are both excluded.
589///
590/// [`MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is
591/// generated first and [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is
592/// generated last. The returned iterator is double-ended, so it may be reversed.
593///
594/// Let $\varphi$ be
595/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
596///
597/// The output is $(\varphi^{-1}(k))_{k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)}$.
598///
599/// The output length is $2^M(2^E-1)-1$.
600/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
601/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
602///
603/// # Complexity per iteration
604/// Constant time and additional memory.
605///
606/// # Examples
607/// ```
608/// use malachite_base::iterators::prefix_to_string;
609/// use malachite_base::num::exhaustive::positive_finite_primitive_floats_increasing;
610/// use malachite_base::num::float::NiceFloat;
611///
612/// assert_eq!(
613/// prefix_to_string(
614/// positive_finite_primitive_floats_increasing::<f32>().map(NiceFloat),
615/// 20
616/// ),
617/// "[1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, \
618/// 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, \
619/// 2.8e-44, ...]"
620/// );
621/// assert_eq!(
622/// prefix_to_string(
623/// positive_finite_primitive_floats_increasing::<f32>()
624/// .rev()
625/// .map(NiceFloat),
626/// 20
627/// ),
628/// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \
629/// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \
630/// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \
631/// 3.4028198e38, 3.4028196e38, ...]"
632/// );
633/// ```
634#[inline]
635pub fn positive_finite_primitive_floats_increasing<T: PrimitiveFloat>()
636-> PrimitiveFloatIncreasingRange<T> {
637 primitive_float_increasing_inclusive_range(T::MIN_POSITIVE_SUBNORMAL, T::MAX_FINITE)
638}
639
640/// Generates all finite negative primitive floats, in ascending order.
641///
642/// Positive and negative zero are both excluded.
643///
644/// [`-MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and
645/// [`-MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is
646/// generated last. The returned iterator is double-ended, so it may be reversed.
647///
648/// Let $\varphi$ be
649/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
650///
651/// The output is $(\varphi^{-1}(k))_{k=1}^{2^M(2^E-1)-1}$.
652///
653/// The output length is $2^M(2^E-1)-1$.
654/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
655/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
656///
657/// # Complexity per iteration
658/// Constant time and additional memory.
659///
660/// # Examples
661/// ```
662/// use malachite_base::iterators::prefix_to_string;
663/// use malachite_base::num::exhaustive::negative_finite_primitive_floats_increasing;
664/// use malachite_base::num::float::NiceFloat;
665///
666/// assert_eq!(
667/// prefix_to_string(
668/// negative_finite_primitive_floats_increasing::<f32>().map(NiceFloat),
669/// 20
670/// ),
671/// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
672/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
673/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
674/// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]"
675/// );
676/// assert_eq!(
677/// prefix_to_string(
678/// negative_finite_primitive_floats_increasing::<f32>()
679/// .rev()
680/// .map(NiceFloat),
681/// 20
682/// ),
683/// "[-1.0e-45, -3.0e-45, -4.0e-45, -6.0e-45, -7.0e-45, -8.0e-45, -1.0e-44, -1.1e-44, \
684/// -1.3e-44, -1.4e-44, -1.5e-44, -1.7e-44, -1.8e-44, -2.0e-44, -2.1e-44, -2.2e-44, -2.4e-44, \
685/// -2.5e-44, -2.7e-44, -2.8e-44, ...]"
686/// );
687/// ```
688#[inline]
689pub fn negative_finite_primitive_floats_increasing<T: PrimitiveFloat>()
690-> PrimitiveFloatIncreasingRange<T> {
691 primitive_float_increasing_inclusive_range(-T::MAX_FINITE, -T::MIN_POSITIVE_SUBNORMAL)
692}
693
694/// Generates all finite nonzero primitive floats, in ascending order.
695///
696/// Positive and negative zero are both excluded.
697///
698/// [-`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and
699/// [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated last. The returned
700/// iterator is double-ended, so it may be reversed.
701///
702/// Let $\varphi$ be
703/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
704///
705/// The output is
706/// $$
707/// (\varphi^{-1}(k))_ {k=1}^{2^M(2^E-1)-1} ⧺ (\varphi^{-1}(k))_ {k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)}
708/// $$.
709///
710/// The output length is $2^{M+1}(2^E-1)-2$.
711/// - For [`f32`], this is $2^{32}-2^{24}-2$, or 4278190078.
712/// - For [`f64`], this is $2^{64}-2^{53}-2$, or 18437736874454810622.
713///
714/// # Complexity per iteration
715/// Constant time and additional memory.
716///
717/// # Examples
718/// ```
719/// use malachite_base::iterators::prefix_to_string;
720/// use malachite_base::num::exhaustive::nonzero_finite_primitive_floats_increasing;
721/// use malachite_base::num::float::NiceFloat;
722///
723/// assert_eq!(
724/// prefix_to_string(
725/// nonzero_finite_primitive_floats_increasing::<f32>().map(NiceFloat),
726/// 20
727/// ),
728/// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
729/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
730/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
731/// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]"
732/// );
733/// assert_eq!(
734/// prefix_to_string(
735/// nonzero_finite_primitive_floats_increasing::<f32>()
736/// .rev()
737/// .map(NiceFloat),
738/// 20
739/// ),
740/// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \
741/// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \
742/// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \
743/// 3.4028198e38, 3.4028196e38, ...]"
744/// );
745/// ```
746#[inline]
747pub fn nonzero_finite_primitive_floats_increasing<T: PrimitiveFloat>()
748-> NonzeroValues<PrimitiveFloatIncreasingRange<T>> {
749 nonzero_values(finite_primitive_floats_increasing())
750}
751
752/// Generates all finite primitive floats, in ascending order.
753///
754/// Positive and negative zero are both included. Negative zero comes first.
755///
756/// [`-MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and
757/// [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated last. The
758/// returned iterator is double-ended, so it may be reversed.
759///
760/// Let $\varphi$ be
761/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
762///
763/// The output is $(\varphi^{-1}(k))_{k=1}^{2^{M+1}(2^E-1)}$.
764///
765/// The output length is $2^{M+1}(2^E-1)$.
766/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
767/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
768///
769/// # Complexity per iteration
770/// Constant time and additional memory.
771///
772/// # Examples
773/// ```
774/// use malachite_base::iterators::prefix_to_string;
775/// use malachite_base::num::exhaustive::finite_primitive_floats_increasing;
776/// use malachite_base::num::float::NiceFloat;
777///
778/// assert_eq!(
779/// prefix_to_string(
780/// finite_primitive_floats_increasing::<f32>().map(NiceFloat),
781/// 20
782/// ),
783/// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
784/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
785/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
786/// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]",
787/// );
788/// assert_eq!(
789/// prefix_to_string(
790/// finite_primitive_floats_increasing::<f32>()
791/// .rev()
792/// .map(NiceFloat),
793/// 20
794/// ),
795/// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \
796/// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \
797/// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \
798/// 3.4028198e38, 3.4028196e38, ...]"
799/// );
800/// ```
801#[inline]
802pub fn finite_primitive_floats_increasing<T: PrimitiveFloat>() -> PrimitiveFloatIncreasingRange<T> {
803 primitive_float_increasing_inclusive_range(-T::MAX_FINITE, T::MAX_FINITE)
804}
805
806/// Generates all positive primitive floats, in ascending order.
807///
808/// Positive and negative zero are both excluded.
809///
810/// [`MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is
811/// generated first and `INFINITY` is generated last. The returned iterator is
812/// double-ended, so it may be reversed.
813///
814/// Let $\varphi$ be
815/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
816///
817/// The output is $(\varphi^{-1}(k))_{k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)+1}$.
818///
819/// The output length is $2^M(2^E-1)$.
820/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
821/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
822///
823/// # Complexity per iteration
824/// Constant time and additional memory.
825///
826/// # Examples
827/// ```
828/// use malachite_base::iterators::prefix_to_string;
829/// use malachite_base::num::exhaustive::positive_primitive_floats_increasing;
830/// use malachite_base::num::float::NiceFloat;
831///
832/// assert_eq!(
833/// prefix_to_string(
834/// positive_primitive_floats_increasing::<f32>().map(NiceFloat),
835/// 20
836/// ),
837/// "[1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, \
838/// 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, \
839/// 2.8e-44, ...]"
840/// );
841/// assert_eq!(
842/// prefix_to_string(
843/// positive_primitive_floats_increasing::<f32>()
844/// .rev()
845/// .map(NiceFloat),
846/// 20
847/// ),
848/// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \
849/// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \
850/// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \
851/// 3.40282e38, 3.4028198e38, ...]"
852/// );
853/// ```
854#[inline]
855pub fn positive_primitive_floats_increasing<T: PrimitiveFloat>() -> PrimitiveFloatIncreasingRange<T>
856{
857 primitive_float_increasing_inclusive_range(T::MIN_POSITIVE_SUBNORMAL, T::INFINITY)
858}
859
860/// Generates all negative primitive floats, in ascending order.
861///
862/// Positive and negative zero are both excluded.
863///
864/// `NEGATIVE_INFINITY` is generated first and
865/// [`-MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is
866/// generated last. The returned iterator is double-ended, so it may be reversed.
867///
868/// Let $\varphi$ be
869/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
870///
871/// The output is $(\varphi^{-1}(k))_{k=0}^{2^M(2^E-1)-1}$.
872///
873/// The output length is $2^M(2^E-1)$.
874/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
875/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
876///
877/// # Complexity per iteration
878/// Constant time and additional memory.
879///
880/// # Examples
881/// ```
882/// use malachite_base::iterators::prefix_to_string;
883/// use malachite_base::num::exhaustive::negative_primitive_floats_increasing;
884/// use malachite_base::num::float::NiceFloat;
885///
886/// assert_eq!(
887/// prefix_to_string(
888/// negative_primitive_floats_increasing::<f32>().map(NiceFloat),
889/// 20
890/// ),
891/// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
892/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
893/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
894/// -3.40282e38, -3.4028198e38, ...]"
895/// );
896/// assert_eq!(
897/// prefix_to_string(
898/// negative_primitive_floats_increasing::<f32>()
899/// .rev()
900/// .map(NiceFloat),
901/// 20
902/// ),
903/// "[-1.0e-45, -3.0e-45, -4.0e-45, -6.0e-45, -7.0e-45, -8.0e-45, -1.0e-44, -1.1e-44, \
904/// -1.3e-44, -1.4e-44, -1.5e-44, -1.7e-44, -1.8e-44, -2.0e-44, -2.1e-44, -2.2e-44, -2.4e-44, \
905/// -2.5e-44, -2.7e-44, -2.8e-44, ...]"
906/// );
907/// ```
908#[inline]
909pub fn negative_primitive_floats_increasing<T: PrimitiveFloat>() -> PrimitiveFloatIncreasingRange<T>
910{
911 primitive_float_increasing_inclusive_range(T::NEGATIVE_INFINITY, -T::MIN_POSITIVE_SUBNORMAL)
912}
913
914/// Generates all nonzero primitive floats, in ascending order.
915///
916/// Positive and negative zero are both excluded.
917///
918/// `NEGATIVE_INFINITY` is generated first and `INFINITY` is generated last. The returned
919/// iterator is double-ended, so it may be reversed.
920///
921/// Let $\varphi$ be
922/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
923///
924/// The output is
925/// $$
926/// (\varphi^{-1}(k))_ {k=0}^{2^M(2^E-1)-1} ⧺ (\varphi^{-1}(k))_
927/// {k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)+1} $$.
928///
929/// The output length is $2^{M+1}(2^E-1)$.
930/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
931/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
932///
933/// # Complexity per iteration
934/// Constant time and additional memory.
935///
936/// # Examples
937/// ```
938/// use malachite_base::iterators::prefix_to_string;
939/// use malachite_base::num::exhaustive::nonzero_primitive_floats_increasing;
940/// use malachite_base::num::float::NiceFloat;
941///
942/// assert_eq!(
943/// prefix_to_string(
944/// nonzero_primitive_floats_increasing::<f32>().map(NiceFloat),
945/// 20
946/// ),
947/// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
948/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
949/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
950/// -3.40282e38, -3.4028198e38, ...]"
951/// );
952/// assert_eq!(
953/// prefix_to_string(
954/// nonzero_primitive_floats_increasing::<f32>()
955/// .rev()
956/// .map(NiceFloat),
957/// 20
958/// ),
959/// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \
960/// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \
961/// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \
962/// 3.40282e38, 3.4028198e38, ...]"
963/// );
964/// ```
965#[inline]
966pub fn nonzero_primitive_floats_increasing<T: PrimitiveFloat>()
967-> NonzeroValues<PrimitiveFloatIncreasingRange<T>> {
968 nonzero_values(primitive_floats_increasing())
969}
970
971/// Generates all primitive floats, except `NaN`, in ascending order.
972///
973/// Positive and negative zero are both included. Negative zero comes first.
974///
975/// `NEGATIVE_INFINITY` is generated first and `INFINITY` is generated last. The returned iterator
976/// is double-ended, so it may be reversed.
977///
978/// Let $\varphi$ be
979/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
980///
981/// The output is $(\varphi^{-1}(k))_{k=0}^{2^{M+1}(2^E-1)+1}$.
982///
983/// The output length is $2^{M+1}(2^E-1)+2$.
984/// - For [`f32`], this is $2^{32}-2^{24}+2$, or 4278190082.
985/// - For [`f64`], this is $2^{64}-2^{53}+2$, or 18437736874454810626.
986///
987/// # Complexity per iteration
988/// Constant time and additional memory.
989///
990/// # Examples
991/// ```
992/// use malachite_base::iterators::prefix_to_string;
993/// use malachite_base::num::exhaustive::primitive_floats_increasing;
994/// use malachite_base::num::float::NiceFloat;
995///
996/// assert_eq!(
997/// prefix_to_string(primitive_floats_increasing::<f32>().map(NiceFloat), 20),
998/// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \
999/// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \
1000/// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \
1001/// -3.40282e38, -3.4028198e38, ...]"
1002/// );
1003/// assert_eq!(
1004/// prefix_to_string(
1005/// primitive_floats_increasing::<f32>().rev().map(NiceFloat),
1006/// 20
1007/// ),
1008/// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \
1009/// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \
1010/// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \
1011/// 3.40282e38, 3.4028198e38, ...]"
1012/// );
1013/// ```
1014#[inline]
1015pub fn primitive_floats_increasing<T: PrimitiveFloat>() -> PrimitiveFloatIncreasingRange<T> {
1016 primitive_float_increasing_inclusive_range(T::NEGATIVE_INFINITY, T::INFINITY)
1017}
1018
1019/// Generates all finite positive primitive floats with a specified `sci_exponent` and precision.
1020///
1021/// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent_and_precision`]; see
1022/// its documentation for more.
1023#[derive(Clone, Debug, Default)]
1024pub struct ConstantPrecisionPrimitiveFloats<T: PrimitiveFloat> {
1025 phantom: PhantomData<*const T>,
1026 n: u64,
1027 increment: u64,
1028 i: u64,
1029 count: u64,
1030}
1031
1032impl<T: PrimitiveFloat> Iterator for ConstantPrecisionPrimitiveFloats<T> {
1033 type Item = T;
1034
1035 fn next(&mut self) -> Option<T> {
1036 if self.i == self.count {
1037 None
1038 } else {
1039 let out = T::from_bits(self.n);
1040 self.i += 1;
1041 if self.i < self.count {
1042 self.n += self.increment;
1043 }
1044 Some(out)
1045 }
1046 }
1047}
1048
1049/// Generates all finite positive primitive floats with a specified `sci_exponent` and precision.
1050///
1051/// Positive and negative zero are both excluded.
1052///
1053/// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s
1054/// < 2$ and $e_s$ is an integer; then $e_s$ is the sci-exponent. An integer $e_s$ occurs as the
1055/// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$.
1056///
1057/// In the above equation, $m$ is a dyadic rational. Let $p$ be the smallest integer such that
1058/// $m2^{p-1}$ is an integer. Then $p$ is the float's precision. It is also the number of
1059/// significant bits.
1060///
1061/// For example, consider the float $100.0$. It may be written as $\frac{25}{16}2^6$, so
1062/// $m=\frac{25}{16}$ and $e=6$. We can write $m$ in binary as $1.1001_2$. Thus, the sci-exponent is
1063/// 6 and the precision is 5.
1064///
1065/// If $p$ is 1, the output length is 1; otherwise, it is $2^{p-2}$.
1066///
1067/// # Complexity per iteration
1068/// Constant time and additional memory.
1069///
1070/// # Panics
1071/// Panics if the sci-exponent is less than
1072/// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than
1073/// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT), or if the precision is
1074/// zero or too large for the given sci-exponent (this can be checked using
1075/// [`max_precision_for_sci_exponent`](super::basic::floats::PrimitiveFloat::max_precision_for_sci_exponent)).
1076///
1077/// # Examples
1078/// ```
1079/// use itertools::Itertools;
1080/// use malachite_base::num::exhaustive::*;
1081/// use malachite_base::num::float::NiceFloat;
1082///
1083/// assert_eq!(
1084/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(0, 3)
1085/// .map(NiceFloat)
1086/// .collect_vec(),
1087/// [1.25, 1.75].iter().copied().map(NiceFloat).collect_vec()
1088/// );
1089/// assert_eq!(
1090/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(0, 5)
1091/// .map(NiceFloat)
1092/// .collect_vec(),
1093/// [1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375]
1094/// .iter()
1095/// .copied()
1096/// .map(NiceFloat)
1097/// .collect_vec()
1098/// );
1099/// assert_eq!(
1100/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(6, 5)
1101/// .map(NiceFloat)
1102/// .collect_vec(),
1103/// [68.0, 76.0, 84.0, 92.0, 100.0, 108.0, 116.0, 124.0]
1104/// .iter()
1105/// .copied()
1106/// .map(NiceFloat)
1107/// .collect_vec()
1108/// );
1109/// ```
1110#[cfg_attr(dylint_lib = "malachite_lints", expect(long_lines))]
1111pub fn exhaustive_primitive_floats_with_sci_exponent_and_precision<T: PrimitiveFloat>(
1112 sci_exponent: i64,
1113 precision: u64,
1114) -> ConstantPrecisionPrimitiveFloats<T> {
1115 assert!(sci_exponent >= T::MIN_EXPONENT);
1116 assert!(sci_exponent <= T::MAX_EXPONENT);
1117 assert_ne!(precision, 0);
1118 let max_precision = T::max_precision_for_sci_exponent(sci_exponent);
1119 assert!(precision <= max_precision);
1120 let increment = u64::power_of_2(max_precision - precision + 1);
1121 let first_mantissa = if precision == 1 {
1122 1
1123 } else {
1124 u64::power_of_2(precision - 1) | 1
1125 };
1126 let first = T::from_integer_mantissa_and_exponent(
1127 first_mantissa,
1128 sci_exponent - i64::exact_from(precision) + 1,
1129 )
1130 .unwrap()
1131 .to_bits();
1132 let count = if precision == 1 {
1133 1
1134 } else {
1135 u64::power_of_2(precision - 2)
1136 };
1137 ConstantPrecisionPrimitiveFloats {
1138 phantom: PhantomData,
1139 n: first,
1140 increment,
1141 i: 0,
1142 count,
1143 }
1144}
1145
1146#[derive(Clone, Debug)]
1147struct PrimitiveFloatsWithExponentGenerator<T: PrimitiveFloat> {
1148 phantom: PhantomData<*const T>,
1149 sci_exponent: i64,
1150}
1151
1152impl<T: PrimitiveFloat>
1153 ExhaustiveDependentPairsYsGenerator<u64, T, ConstantPrecisionPrimitiveFloats<T>>
1154 for PrimitiveFloatsWithExponentGenerator<T>
1155{
1156 #[inline]
1157 fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats<T> {
1158 exhaustive_primitive_floats_with_sci_exponent_and_precision(self.sci_exponent, precision)
1159 }
1160}
1161
1162#[inline]
1163fn exhaustive_primitive_floats_with_sci_exponent_helper<T: PrimitiveFloat>(
1164 sci_exponent: i64,
1165) -> LexDependentPairs<
1166 u64,
1167 T,
1168 PrimitiveFloatsWithExponentGenerator<T>,
1169 PrimitiveIntIncreasingRange<u64>,
1170 ConstantPrecisionPrimitiveFloats<T>,
1171> {
1172 lex_dependent_pairs(
1173 primitive_int_increasing_inclusive_range(
1174 1,
1175 T::max_precision_for_sci_exponent(sci_exponent),
1176 ),
1177 PrimitiveFloatsWithExponentGenerator {
1178 phantom: PhantomData,
1179 sci_exponent,
1180 },
1181 )
1182}
1183
1184/// Generates all positive finite primitive floats with a specified `sci_exponent`.
1185///
1186/// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent`]; see its
1187/// documentation for more.
1188#[derive(Clone, Debug)]
1189pub struct ExhaustivePrimitiveFloatsWithExponent<T: PrimitiveFloat>(
1190 LexDependentPairs<
1191 u64,
1192 T,
1193 PrimitiveFloatsWithExponentGenerator<T>,
1194 PrimitiveIntIncreasingRange<u64>,
1195 ConstantPrecisionPrimitiveFloats<T>,
1196 >,
1197);
1198
1199impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatsWithExponent<T> {
1200 type Item = T;
1201
1202 #[inline]
1203 fn next(&mut self) -> Option<T> {
1204 self.0.next().map(|p| p.1)
1205 }
1206}
1207
1208/// Generates all positive finite primitive floats with a specified sci-exponent.
1209///
1210/// Positive and negative zero are both excluded.
1211///
1212/// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s
1213/// < 2$ and $e_s$ is an integer; then $e$ is the sci-exponent. An integer $e_s$ occurs as the
1214/// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$.
1215///
1216/// If $e_s \geq 2-2^{E-1}$ (the float is normal), the output length is $2^M$.
1217/// - For [`f32`], this is $2^{23}$, or 8388608.
1218/// - For [`f64`], this is $2^{52}$, or 4503599627370496.
1219///
1220/// If $e_s < 2-2^{E-1}$ (the float is subnormal), the output length is $2^{e_s+2^{E-1}+M-2}$.
1221/// - For [`f32`], this is $2^{e_s+149}$.
1222/// - For [`f64`], this is $2^{e_s+1074}$.
1223///
1224/// # Complexity per iteration
1225/// Constant time and additional memory.
1226///
1227/// # Panics
1228/// Panics if the sci-exponent is less than
1229/// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than
1230/// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT).
1231///
1232/// # Examples
1233/// ```
1234/// use itertools::Itertools;
1235/// use malachite_base::iterators::prefix_to_string;
1236/// use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent;
1237/// use malachite_base::num::float::NiceFloat;
1238///
1239/// assert_eq!(
1240/// prefix_to_string(
1241/// exhaustive_primitive_floats_with_sci_exponent::<f32>(0).map(NiceFloat),
1242/// 20
1243/// ),
1244/// "[1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, \
1245/// 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, ...]",
1246/// );
1247/// assert_eq!(
1248/// prefix_to_string(
1249/// exhaustive_primitive_floats_with_sci_exponent::<f32>(4).map(NiceFloat),
1250/// 20
1251/// ),
1252/// "[16.0, 24.0, 20.0, 28.0, 18.0, 22.0, 26.0, 30.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, \
1253/// 29.0, 31.0, 16.5, 17.5, 18.5, 19.5, ...]"
1254/// );
1255/// assert_eq!(
1256/// exhaustive_primitive_floats_with_sci_exponent::<f32>(-147)
1257/// .map(NiceFloat)
1258/// .collect_vec(),
1259/// [6.0e-45, 8.0e-45, 7.0e-45, 1.0e-44]
1260/// .iter()
1261/// .copied()
1262/// .map(NiceFloat)
1263/// .collect_vec()
1264/// );
1265/// ```
1266#[inline]
1267pub fn exhaustive_primitive_floats_with_sci_exponent<T: PrimitiveFloat>(
1268 sci_exponent: i64,
1269) -> ExhaustivePrimitiveFloatsWithExponent<T> {
1270 ExhaustivePrimitiveFloatsWithExponent(exhaustive_primitive_floats_with_sci_exponent_helper(
1271 sci_exponent,
1272 ))
1273}
1274
1275#[derive(Clone, Debug)]
1276struct ExhaustivePositiveFinitePrimitiveFloatsGenerator<T: PrimitiveFloat> {
1277 phantom: PhantomData<*const T>,
1278}
1279
1280impl<T: PrimitiveFloat>
1281 ExhaustiveDependentPairsYsGenerator<i64, T, ExhaustivePrimitiveFloatsWithExponent<T>>
1282 for ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>
1283{
1284 #[inline]
1285 fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponent<T> {
1286 exhaustive_primitive_floats_with_sci_exponent(sci_exponent)
1287 }
1288}
1289
1290#[inline]
1291fn exhaustive_positive_finite_primitive_floats_helper<T: PrimitiveFloat>()
1292-> ExhaustiveDependentPairs<
1293 i64,
1294 T,
1295 RulerSequence<usize>,
1296 ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>,
1297 ExhaustiveSignedRange<i64>,
1298 ExhaustivePrimitiveFloatsWithExponent<T>,
1299> {
1300 exhaustive_dependent_pairs(
1301 ruler_sequence(),
1302 exhaustive_signed_inclusive_range(T::MIN_EXPONENT, T::MAX_EXPONENT),
1303 ExhaustivePositiveFinitePrimitiveFloatsGenerator {
1304 phantom: PhantomData,
1305 },
1306 )
1307}
1308
1309/// Generates all positive finite primitive floats.
1310///
1311/// This `struct` is created by [`exhaustive_positive_finite_primitive_floats`]; see its
1312/// documentation for more.
1313#[derive(Clone, Debug)]
1314pub struct ExhaustivePositiveFinitePrimitiveFloats<T: PrimitiveFloat>(
1315 ExhaustiveDependentPairs<
1316 i64,
1317 T,
1318 RulerSequence<usize>,
1319 ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>,
1320 ExhaustiveSignedRange<i64>,
1321 ExhaustivePrimitiveFloatsWithExponent<T>,
1322 >,
1323);
1324
1325impl<T: PrimitiveFloat> Iterator for ExhaustivePositiveFinitePrimitiveFloats<T> {
1326 type Item = T;
1327
1328 #[inline]
1329 fn next(&mut self) -> Option<T> {
1330 self.0.next().map(|p| p.1)
1331 }
1332}
1333
1334/// Generates all positive finite primitive floats.
1335///
1336/// Positive and negative zero are both excluded.
1337///
1338/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1339/// ascending order instead, use [`positive_finite_primitive_floats_increasing`].
1340///
1341/// The output length is $2^M(2^E-1)-1$.
1342/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
1343/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
1344///
1345/// # Complexity per iteration
1346/// Constant time and additional memory.
1347///
1348/// # Examples
1349/// ```
1350/// use malachite_base::iterators::prefix_to_string;
1351/// use malachite_base::num::exhaustive::exhaustive_positive_finite_primitive_floats;
1352/// use malachite_base::num::float::NiceFloat;
1353///
1354/// assert_eq!(
1355/// prefix_to_string(
1356/// exhaustive_positive_finite_primitive_floats::<f32>().map(NiceFloat),
1357/// 50
1358/// ),
1359/// "[1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, \
1360/// 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, \
1361/// 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, \
1362/// 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ...]"
1363/// );
1364/// ```
1365#[inline]
1366pub fn exhaustive_positive_finite_primitive_floats<T: PrimitiveFloat>()
1367-> ExhaustivePositiveFinitePrimitiveFloats<T> {
1368 ExhaustivePositiveFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats_helper())
1369}
1370
1371/// Generates all negative finite primitive floats.
1372///
1373/// This `struct` is created by [`exhaustive_negative_finite_primitive_floats`]; see its
1374/// documentation for more.
1375#[derive(Clone, Debug)]
1376pub struct ExhaustiveNegativeFinitePrimitiveFloats<T: PrimitiveFloat>(
1377 ExhaustivePositiveFinitePrimitiveFloats<T>,
1378);
1379
1380impl<T: PrimitiveFloat> Iterator for ExhaustiveNegativeFinitePrimitiveFloats<T> {
1381 type Item = T;
1382
1383 #[inline]
1384 fn next(&mut self) -> Option<T> {
1385 self.0.next().map(|f| -f)
1386 }
1387}
1388
1389/// Generates all negative finite primitive floats.
1390///
1391/// Positive and negative zero are both excluded.
1392///
1393/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1394/// ascending order instead, use [`negative_finite_primitive_floats_increasing`].
1395///
1396/// The output length is $2^M(2^E-1)-1$.
1397/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
1398/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
1399///
1400/// # Complexity per iteration
1401/// Constant time and additional memory.
1402///
1403/// # Examples
1404/// ```
1405/// use malachite_base::iterators::prefix_to_string;
1406/// use malachite_base::num::exhaustive::exhaustive_negative_finite_primitive_floats;
1407/// use malachite_base::num::float::NiceFloat;
1408///
1409/// assert_eq!(
1410/// prefix_to_string(
1411/// exhaustive_negative_finite_primitive_floats::<f32>().map(NiceFloat),
1412/// 50
1413/// ),
1414/// "[-1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, \
1415/// -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, \
1416/// -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, \
1417/// -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, \
1418/// -1.40625, -2.875, -1.46875, -0.375, -1.53125, -3.125, ...]"
1419/// );
1420/// ```
1421#[inline]
1422pub fn exhaustive_negative_finite_primitive_floats<T: PrimitiveFloat>()
1423-> ExhaustiveNegativeFinitePrimitiveFloats<T> {
1424 ExhaustiveNegativeFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats())
1425}
1426
1427/// Generates all nonzero finite primitive floats.
1428///
1429/// This `struct` is created by [`exhaustive_nonzero_finite_primitive_floats`]; see its
1430/// documentation for more.
1431#[derive(Clone, Debug)]
1432pub struct ExhaustiveNonzeroFinitePrimitiveFloats<T: PrimitiveFloat> {
1433 toggle: bool,
1434 xs: ExhaustivePositiveFinitePrimitiveFloats<T>,
1435 x: T,
1436}
1437
1438impl<T: PrimitiveFloat> Iterator for ExhaustiveNonzeroFinitePrimitiveFloats<T> {
1439 type Item = T;
1440
1441 #[inline]
1442 fn next(&mut self) -> Option<T> {
1443 self.toggle.not_assign();
1444 Some(if self.toggle {
1445 self.x = self.xs.next().unwrap();
1446 self.x
1447 } else {
1448 -self.x
1449 })
1450 }
1451}
1452
1453/// Generates all nonzero finite primitive floats.
1454///
1455/// Positive and negative zero are both excluded.
1456///
1457/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1458/// ascending order instead, use [`nonzero_finite_primitive_floats_increasing`].
1459///
1460/// The output length is $2^{M+1}(2^E-1)-2$.
1461/// - For [`f32`], this is $2^{32}-2^{24}-2$, or 4278190078.
1462/// - For [`f64`], this is $2^{64}-2^{53}-2$, or 18437736874454810622.
1463///
1464/// # Complexity per iteration
1465/// Constant time and additional memory.
1466///
1467/// # Examples
1468/// ```
1469/// use malachite_base::iterators::prefix_to_string;
1470/// use malachite_base::num::exhaustive::exhaustive_nonzero_finite_primitive_floats;
1471/// use malachite_base::num::float::NiceFloat;
1472///
1473/// assert_eq!(
1474/// prefix_to_string(
1475/// exhaustive_nonzero_finite_primitive_floats::<f32>().map(NiceFloat),
1476/// 50
1477/// ),
1478/// "[1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, \
1479/// -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, \
1480/// 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, \
1481/// 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ...]"
1482/// );
1483/// ```
1484#[inline]
1485pub fn exhaustive_nonzero_finite_primitive_floats<T: PrimitiveFloat>()
1486-> ExhaustiveNonzeroFinitePrimitiveFloats<T> {
1487 ExhaustiveNonzeroFinitePrimitiveFloats {
1488 toggle: false,
1489 xs: exhaustive_positive_finite_primitive_floats(),
1490 x: T::ZERO,
1491 }
1492}
1493
1494pub type ExhaustiveFinitePrimitiveFloats<T> =
1495 Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>>;
1496
1497/// Generates all finite primitive floats.
1498///
1499/// Positive and negative zero are both included.
1500///
1501/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1502/// ascending order instead, use [`finite_primitive_floats_increasing`].
1503///
1504/// The output length is $2^{M+1}(2^E-1)$.
1505/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
1506/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
1507///
1508/// # Complexity per iteration
1509/// Constant time and additional memory.
1510///
1511/// # Examples
1512/// ```
1513/// use malachite_base::iterators::prefix_to_string;
1514/// use malachite_base::num::exhaustive::exhaustive_finite_primitive_floats;
1515/// use malachite_base::num::float::NiceFloat;
1516///
1517/// assert_eq!(
1518/// prefix_to_string(
1519/// exhaustive_finite_primitive_floats::<f32>().map(NiceFloat),
1520/// 50
1521/// ),
1522/// "[0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, \
1523/// -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, \
1524/// 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, \
1525/// 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ...]"
1526/// );
1527/// ```
1528#[inline]
1529pub fn exhaustive_finite_primitive_floats<T: PrimitiveFloat>()
1530-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1531 ::alloc::vec![T::ZERO, T::NEGATIVE_ZERO]
1532 .into_iter()
1533 .chain(exhaustive_nonzero_finite_primitive_floats())
1534}
1535
1536/// Generates all positive primitive floats.
1537///
1538/// Positive and negative zero are both excluded.
1539///
1540/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1541/// ascending order instead, use [`positive_primitive_floats_increasing`].
1542///
1543/// The output length is $2^M(2^E-1)$.
1544/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
1545/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
1546///
1547/// # Complexity per iteration
1548/// Constant time and additional memory.
1549///
1550/// # Examples
1551/// ```
1552/// use malachite_base::iterators::prefix_to_string;
1553/// use malachite_base::num::exhaustive::exhaustive_positive_primitive_floats;
1554/// use malachite_base::num::float::NiceFloat;
1555///
1556/// assert_eq!(
1557/// prefix_to_string(
1558/// exhaustive_positive_primitive_floats::<f32>().map(NiceFloat),
1559/// 50
1560/// ),
1561/// "[Infinity, 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, \
1562/// 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, \
1563/// 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, \
1564/// 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, \
1565/// 1.53125, ...]"
1566/// );
1567/// ```
1568#[inline]
1569pub fn exhaustive_positive_primitive_floats<T: PrimitiveFloat>()
1570-> Chain<Once<T>, ExhaustivePositiveFinitePrimitiveFloats<T>> {
1571 once(T::INFINITY).chain(exhaustive_positive_finite_primitive_floats())
1572}
1573
1574/// Generates all negative primitive floats.
1575///
1576/// Positive and negative zero are both excluded.
1577///
1578/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1579/// ascending order instead, use [`negative_primitive_floats_increasing`].
1580///
1581/// The output length is $2^M(2^E-1)$.
1582/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
1583/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
1584///
1585/// # Complexity per iteration
1586/// Constant time and additional memory.
1587///
1588/// # Examples
1589/// ```
1590/// use malachite_base::iterators::prefix_to_string;
1591/// use malachite_base::num::exhaustive::exhaustive_negative_primitive_floats;
1592/// use malachite_base::num::float::NiceFloat;
1593///
1594/// assert_eq!(
1595/// prefix_to_string(
1596/// exhaustive_negative_primitive_floats::<f32>().map(NiceFloat),
1597/// 50
1598/// ),
1599/// "[-Infinity, -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, \
1600/// -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, \
1601/// -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, \
1602/// -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, \
1603/// -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, ...]"
1604/// );
1605/// ```
1606#[inline]
1607pub fn exhaustive_negative_primitive_floats<T: PrimitiveFloat>()
1608-> Chain<Once<T>, ExhaustiveNegativeFinitePrimitiveFloats<T>> {
1609 once(T::NEGATIVE_INFINITY).chain(exhaustive_negative_finite_primitive_floats())
1610}
1611
1612/// Generates all nonzero primitive floats.
1613///
1614/// Positive and negative zero are both excluded. NaN is excluded as well.
1615///
1616/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1617/// ascending order instead, use [`nonzero_primitive_floats_increasing`].
1618///
1619/// The output length is $2^{M+1}(2^E-1)$.
1620/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
1621/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
1622///
1623/// # Complexity per iteration
1624/// Constant time and additional memory.
1625///
1626/// # Examples
1627/// ```
1628/// use malachite_base::iterators::prefix_to_string;
1629/// use malachite_base::num::exhaustive::exhaustive_nonzero_primitive_floats;
1630/// use malachite_base::num::float::NiceFloat;
1631///
1632/// assert_eq!(
1633/// prefix_to_string(
1634/// exhaustive_nonzero_primitive_floats::<f32>().map(NiceFloat),
1635/// 50
1636/// ),
1637/// "[Infinity, -Infinity, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, \
1638/// -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, \
1639/// 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, \
1640/// 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, \
1641/// ...]"
1642/// );
1643/// ```
1644#[inline]
1645pub fn exhaustive_nonzero_primitive_floats<T: PrimitiveFloat>()
1646-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1647 ::alloc::vec![T::INFINITY, T::NEGATIVE_INFINITY]
1648 .into_iter()
1649 .chain(exhaustive_nonzero_finite_primitive_floats())
1650}
1651
1652/// Generates all primitive floats.
1653///
1654/// Positive and negative zero are both included.
1655///
1656/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats
1657/// (except `NaN`) in ascending order instead, use [`primitive_floats_increasing`].
1658///
1659/// The output length is $2^{M+1}(2^E-1)+2$.
1660/// - For [`f32`], this is $2^{32}-2^{24}+2$, or 4278190082.
1661/// - For [`f64`], this is $2^{64}-2^{53}+2$, or 18437736874454810626.
1662///
1663/// # Complexity per iteration
1664/// Constant time and additional memory.
1665///
1666/// # Examples
1667/// ```
1668/// use malachite_base::iterators::prefix_to_string;
1669/// use malachite_base::num::exhaustive::exhaustive_primitive_floats;
1670/// use malachite_base::num::float::NiceFloat;
1671///
1672/// assert_eq!(
1673/// prefix_to_string(exhaustive_primitive_floats::<f32>().map(NiceFloat), 50),
1674/// "[NaN, Infinity, -Infinity, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, \
1675/// -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, \
1676/// -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, \
1677/// -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, ...]"
1678/// );
1679/// ```
1680#[inline]
1681pub fn exhaustive_primitive_floats<T: PrimitiveFloat>()
1682-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1683 ::alloc::vec![T::NAN, T::INFINITY, T::NEGATIVE_INFINITY, T::ZERO, T::NEGATIVE_ZERO]
1684 .into_iter()
1685 .chain(exhaustive_nonzero_finite_primitive_floats())
1686}
1687
1688pub_test! {exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range<T: PrimitiveFloat>(
1689 a: T,
1690 b: T,
1691 sci_exponent: i64,
1692 precision: u64
1693) -> ConstantPrecisionPrimitiveFloats<T> {
1694 assert!(a.is_finite());
1695 assert!(b.is_finite());
1696 assert!(a > T::ZERO);
1697 assert!(b > T::ZERO);
1698 assert!(sci_exponent >= T::MIN_EXPONENT);
1699 assert!(sci_exponent <= T::MAX_EXPONENT);
1700 let (am, ae) = a.raw_mantissa_and_exponent();
1701 let (bm, be) = b.raw_mantissa_and_exponent();
1702 let ae_actual_sci_exponent = if ae == 0 {
1703 i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1
1704 } else {
1705 i64::wrapping_from(ae) - T::MAX_EXPONENT
1706 };
1707 let be_actual_sci_exponent = if be == 0 {
1708 i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1
1709 } else {
1710 i64::wrapping_from(be) - T::MAX_EXPONENT
1711 };
1712 assert_eq!(ae_actual_sci_exponent, sci_exponent);
1713 assert_eq!(be_actual_sci_exponent, sci_exponent);
1714 assert!(am <= bm);
1715 assert_ne!(precision, 0);
1716 let max_precision = T::max_precision_for_sci_exponent(sci_exponent);
1717 assert!(precision <= max_precision);
1718 if precision == 1 && am == 0 {
1719 return ConstantPrecisionPrimitiveFloats {
1720 phantom: PhantomData,
1721 n: a.to_bits(),
1722 increment: 0,
1723 i: 0,
1724 count: 1,
1725 };
1726 }
1727 let trailing_zeros = max_precision - precision;
1728 let increment = u64::power_of_2(trailing_zeros + 1);
1729 let mut start_mantissa = am.round_to_multiple_of_power_of_2(trailing_zeros, Up).0;
1730 if !start_mantissa.get_bit(trailing_zeros) {
1731 start_mantissa.set_bit(trailing_zeros);
1732 }
1733 if start_mantissa > bm {
1734 return ConstantPrecisionPrimitiveFloats::default();
1735 }
1736 let mut end_mantissa = bm.round_to_multiple_of_power_of_2(trailing_zeros, Down).0;
1737 if !end_mantissa.get_bit(trailing_zeros) {
1738 let adjust = u64::power_of_2(trailing_zeros);
1739 if adjust > end_mantissa {
1740 return ConstantPrecisionPrimitiveFloats::default();
1741 }
1742 end_mantissa -= adjust;
1743 }
1744 assert!(start_mantissa <= end_mantissa);
1745 let count = ((end_mantissa - start_mantissa) >> (trailing_zeros + 1)) + 1;
1746 let first = T::from_raw_mantissa_and_exponent(start_mantissa, ae).to_bits();
1747 ConstantPrecisionPrimitiveFloats {
1748 phantom: PhantomData,
1749 n: first,
1750 increment,
1751 i: 0,
1752 count,
1753 }
1754}}
1755
1756#[derive(Clone, Debug)]
1757struct PrimitiveFloatsWithExponentInRangeGenerator<T: PrimitiveFloat> {
1758 a: T,
1759 b: T,
1760 sci_exponent: i64,
1761 phantom: PhantomData<*const T>,
1762}
1763
1764impl<T: PrimitiveFloat>
1765 ExhaustiveDependentPairsYsGenerator<u64, T, ConstantPrecisionPrimitiveFloats<T>>
1766 for PrimitiveFloatsWithExponentInRangeGenerator<T>
1767{
1768 #[inline]
1769 fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats<T> {
1770 exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range(
1771 self.a,
1772 self.b,
1773 self.sci_exponent,
1774 precision,
1775 )
1776 }
1777}
1778
1779#[inline]
1780fn exhaustive_primitive_floats_with_sci_exponent_in_range_helper<T: PrimitiveFloat>(
1781 a: T,
1782 b: T,
1783 sci_exponent: i64,
1784) -> LexDependentPairs<
1785 u64,
1786 T,
1787 PrimitiveFloatsWithExponentInRangeGenerator<T>,
1788 PrimitiveIntIncreasingRange<u64>,
1789 ConstantPrecisionPrimitiveFloats<T>,
1790> {
1791 lex_dependent_pairs(
1792 primitive_int_increasing_inclusive_range(
1793 1,
1794 T::max_precision_for_sci_exponent(sci_exponent),
1795 ),
1796 PrimitiveFloatsWithExponentInRangeGenerator {
1797 a,
1798 b,
1799 sci_exponent,
1800 phantom: PhantomData,
1801 },
1802 )
1803}
1804
1805#[doc(hidden)]
1806#[derive(Clone, Debug)]
1807pub struct ExhaustivePrimitiveFloatsWithExponentInRange<T: PrimitiveFloat>(
1808 LexDependentPairs<
1809 u64,
1810 T,
1811 PrimitiveFloatsWithExponentInRangeGenerator<T>,
1812 PrimitiveIntIncreasingRange<u64>,
1813 ConstantPrecisionPrimitiveFloats<T>,
1814 >,
1815);
1816
1817impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1818 type Item = T;
1819
1820 #[inline]
1821 fn next(&mut self) -> Option<T> {
1822 self.0.next().map(|p| p.1)
1823 }
1824}
1825
1826#[doc(hidden)]
1827#[inline]
1828pub fn exhaustive_primitive_floats_with_sci_exponent_in_range<T: PrimitiveFloat>(
1829 a: T,
1830 b: T,
1831 sci_exponent: i64,
1832) -> ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1833 ExhaustivePrimitiveFloatsWithExponentInRange(
1834 exhaustive_primitive_floats_with_sci_exponent_in_range_helper(a, b, sci_exponent),
1835 )
1836}
1837
1838#[derive(Clone, Debug)]
1839struct ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T: PrimitiveFloat> {
1840 a: T,
1841 b: T,
1842 a_sci_exponent: i64,
1843 b_sci_exponent: i64,
1844 phantom: PhantomData<*const T>,
1845}
1846
1847impl<T: PrimitiveFloat>
1848 ExhaustiveDependentPairsYsGenerator<i64, T, ExhaustivePrimitiveFloatsWithExponentInRange<T>>
1849 for ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>
1850{
1851 #[inline]
1852 fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1853 let a = if sci_exponent == self.a_sci_exponent {
1854 self.a
1855 } else {
1856 T::from_integer_mantissa_and_exponent(1, sci_exponent).unwrap()
1857 };
1858 let b = if sci_exponent == self.b_sci_exponent {
1859 self.b
1860 } else {
1861 T::from_integer_mantissa_and_exponent(1, sci_exponent + 1)
1862 .unwrap()
1863 .next_lower()
1864 };
1865 exhaustive_primitive_floats_with_sci_exponent_in_range(a, b, sci_exponent)
1866 }
1867}
1868
1869#[inline]
1870fn exhaustive_positive_finite_primitive_floats_in_range_helper<T: PrimitiveFloat>(
1871 a: T,
1872 b: T,
1873) -> ExhaustiveDependentPairs<
1874 i64,
1875 T,
1876 RulerSequence<usize>,
1877 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>,
1878 ExhaustiveSignedRange<i64>,
1879 ExhaustivePrimitiveFloatsWithExponentInRange<T>,
1880> {
1881 assert!(a.is_finite());
1882 assert!(b.is_finite());
1883 assert!(a > T::ZERO);
1884 assert!(a <= b);
1885 let (am, ae) = a.raw_mantissa_and_exponent();
1886 let (bm, be) = b.raw_mantissa_and_exponent();
1887 let a_sci_exponent = if ae == 0 {
1888 i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1
1889 } else {
1890 i64::wrapping_from(ae) - T::MAX_EXPONENT
1891 };
1892 let b_sci_exponent = if be == 0 {
1893 i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1
1894 } else {
1895 i64::wrapping_from(be) - T::MAX_EXPONENT
1896 };
1897 exhaustive_dependent_pairs(
1898 ruler_sequence(),
1899 exhaustive_signed_inclusive_range(a_sci_exponent, b_sci_exponent),
1900 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator {
1901 a,
1902 b,
1903 a_sci_exponent,
1904 b_sci_exponent,
1905 phantom: PhantomData,
1906 },
1907 )
1908}
1909
1910#[doc(hidden)]
1911#[derive(Clone, Debug)]
1912pub struct ExhaustivePositiveFinitePrimitiveFloatsInRange<T: PrimitiveFloat>(
1913 ExhaustiveDependentPairs<
1914 i64,
1915 T,
1916 RulerSequence<usize>,
1917 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>,
1918 ExhaustiveSignedRange<i64>,
1919 ExhaustivePrimitiveFloatsWithExponentInRange<T>,
1920 >,
1921);
1922
1923impl<T: PrimitiveFloat> Iterator for ExhaustivePositiveFinitePrimitiveFloatsInRange<T> {
1924 type Item = T;
1925
1926 #[inline]
1927 fn next(&mut self) -> Option<T> {
1928 self.0.next().map(|p| p.1)
1929 }
1930}
1931
1932#[doc(hidden)]
1933#[inline]
1934pub fn exhaustive_positive_finite_primitive_floats_in_range<T: PrimitiveFloat>(
1935 a: T,
1936 b: T,
1937) -> ExhaustivePositiveFinitePrimitiveFloatsInRange<T> {
1938 ExhaustivePositiveFinitePrimitiveFloatsInRange(
1939 exhaustive_positive_finite_primitive_floats_in_range_helper(a, b),
1940 )
1941}
1942
1943#[doc(hidden)]
1944#[derive(Clone, Debug)]
1945pub enum ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T: PrimitiveFloat> {
1946 AllPositive(ExhaustivePositiveFinitePrimitiveFloatsInRange<T>),
1947 AllNegative(ExhaustivePositiveFinitePrimitiveFloatsInRange<T>),
1948 PositiveAndNegative(
1949 bool,
1950 ExhaustivePositiveFinitePrimitiveFloatsInRange<T>,
1951 ExhaustivePositiveFinitePrimitiveFloatsInRange<T>,
1952 ),
1953}
1954
1955impl<T: PrimitiveFloat> Iterator for ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T> {
1956 type Item = T;
1957
1958 fn next(&mut self) -> Option<T> {
1959 match self {
1960 Self::AllPositive(xs) => xs.next(),
1961 Self::AllNegative(xs) => xs.next().map(T::neg),
1962 Self::PositiveAndNegative(toggle, pos_xs, neg_xs) => {
1963 toggle.not_assign();
1964 if *toggle {
1965 pos_xs.next().or_else(|| neg_xs.next().map(T::neg))
1966 } else {
1967 neg_xs.next().map(T::neg).or_else(|| pos_xs.next())
1968 }
1969 }
1970 }
1971 }
1972}
1973
1974#[doc(hidden)]
1975#[inline]
1976pub fn exhaustive_nonzero_finite_primitive_floats_in_range<T: PrimitiveFloat>(
1977 a: T,
1978 b: T,
1979) -> ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T> {
1980 assert!(a.is_finite());
1981 assert!(b.is_finite());
1982 assert!(a != T::ZERO);
1983 assert!(b != T::ZERO);
1984 assert!(a <= b);
1985 if a > T::ZERO {
1986 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllPositive(
1987 exhaustive_positive_finite_primitive_floats_in_range(a, b),
1988 )
1989 } else if b < T::ZERO {
1990 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllNegative(
1991 exhaustive_positive_finite_primitive_floats_in_range(-b, -a),
1992 )
1993 } else {
1994 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::PositiveAndNegative(
1995 false,
1996 exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, b),
1997 exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, -a),
1998 )
1999 }
2000}
2001
2002/// Generates all primitive floats in an interval.
2003///
2004/// This `enum` is created by [`exhaustive_primitive_float_range`] and
2005/// [`exhaustive_primitive_float_inclusive_range`]; see their documentation for more.
2006#[allow(clippy::large_enum_variant)]
2007#[derive(Clone, Debug)]
2008pub enum ExhaustivePrimitiveFloatInclusiveRange<T: PrimitiveFloat> {
2009 JustSpecials(IntoIter<T>),
2010 NotJustSpecials(Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T>>),
2011}
2012
2013impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatInclusiveRange<T> {
2014 type Item = T;
2015
2016 fn next(&mut self) -> Option<T> {
2017 match self {
2018 Self::JustSpecials(xs) => xs.next(),
2019 Self::NotJustSpecials(xs) => xs.next(),
2020 }
2021 }
2022}
2023
2024/// Generates all primitive floats in the half-open interval $[a, b)$.
2025///
2026/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
2027/// than zero.
2028///
2029/// The floats are generated in a way such that simpler floats (with lower precision) are generated
2030/// first. To generate floats in ascending order instead, use [`primitive_float_increasing_range`]
2031/// instead.
2032///
2033/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
2034/// `NiceFloat(b)` are equal, the range is empty.
2035///
2036/// Let $\varphi$ be
2037/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
2038///
2039/// The output length is $\varphi(b) - \varphi(a)$.
2040///
2041/// # Complexity per iteration
2042/// Constant time and additional memory.
2043///
2044/// # Panics
2045/// Panics if `NiceFloat(a) > NiceFloat(b)`.
2046///
2047/// # Examples
2048/// ```
2049/// use malachite_base::iterators::prefix_to_string;
2050/// use malachite_base::num::exhaustive::exhaustive_primitive_float_range;
2051/// use malachite_base::num::float::NiceFloat;
2052///
2053/// assert_eq!(
2054/// prefix_to_string(
2055/// exhaustive_primitive_float_range::<f32>(core::f32::consts::E, core::f32::consts::PI)
2056/// .map(NiceFloat),
2057/// 50
2058/// ),
2059/// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \
2060/// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \
2061/// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \
2062/// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \
2063/// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \
2064/// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]"
2065/// );
2066/// ```
2067#[inline]
2068pub fn exhaustive_primitive_float_range<T: PrimitiveFloat>(
2069 a: T,
2070 b: T,
2071) -> ExhaustivePrimitiveFloatInclusiveRange<T> {
2072 assert!(!a.is_nan());
2073 assert!(!b.is_nan());
2074 assert!(NiceFloat(a) <= NiceFloat(b));
2075 if NiceFloat(a) == NiceFloat(b) {
2076 ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(Vec::new().into_iter())
2077 } else {
2078 exhaustive_primitive_float_inclusive_range(a, b.next_lower())
2079 }
2080}
2081
2082/// Generates all primitive floats in the closed interval $[a, b]$.
2083///
2084/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
2085/// than zero.
2086///
2087/// The floats are generated in a way such that simpler floats (with lower precision) are generated
2088/// first. To generate floats in ascending order instead, use
2089/// `primitive_float_increasing_inclusive_range` instead.
2090///
2091/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
2092/// `NiceFloat(b)` are equal, the range contains a single element.
2093///
2094/// Let $\varphi$ be
2095/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
2096///
2097/// The output length is $\varphi(b) - \varphi(a) + 1$.
2098///
2099/// # Complexity per iteration
2100/// Constant time and additional memory.
2101///
2102/// # Panics
2103/// Panics if `NiceFloat(a) > NiceFloat(b)`.
2104///
2105/// # Examples
2106/// ```
2107/// use malachite_base::iterators::prefix_to_string;
2108/// use malachite_base::num::exhaustive::exhaustive_primitive_float_inclusive_range;
2109/// use malachite_base::num::float::NiceFloat;
2110///
2111/// assert_eq!(
2112/// prefix_to_string(
2113/// exhaustive_primitive_float_inclusive_range::<f32>(
2114/// core::f32::consts::E,
2115/// core::f32::consts::PI
2116/// )
2117/// .map(NiceFloat),
2118/// 50
2119/// ),
2120/// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \
2121/// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \
2122/// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \
2123/// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \
2124/// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \
2125/// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]"
2126/// );
2127/// ```
2128#[inline]
2129pub fn exhaustive_primitive_float_inclusive_range<T: PrimitiveFloat>(
2130 mut a: T,
2131 mut b: T,
2132) -> ExhaustivePrimitiveFloatInclusiveRange<T> {
2133 assert!(!a.is_nan());
2134 assert!(!b.is_nan());
2135 assert!(NiceFloat(a) <= NiceFloat(b));
2136 let mut specials = Vec::new();
2137 if b == T::INFINITY {
2138 specials.push(T::INFINITY);
2139 if a == T::INFINITY {
2140 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2141 }
2142 b = T::MAX_FINITE;
2143 }
2144 if a == T::NEGATIVE_INFINITY {
2145 specials.push(T::NEGATIVE_INFINITY);
2146 if b == T::NEGATIVE_INFINITY {
2147 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2148 }
2149 a = -T::MAX_FINITE;
2150 }
2151 if NiceFloat(a) <= NiceFloat(T::ZERO) && NiceFloat(b) >= NiceFloat(T::ZERO) {
2152 specials.push(T::ZERO);
2153 }
2154 if NiceFloat(a) <= NiceFloat(T::NEGATIVE_ZERO) && NiceFloat(b) >= NiceFloat(T::NEGATIVE_ZERO) {
2155 specials.push(T::NEGATIVE_ZERO);
2156 }
2157 if a == T::ZERO {
2158 if b == T::ZERO {
2159 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2160 }
2161 a = T::MIN_POSITIVE_SUBNORMAL;
2162 }
2163 if b == T::ZERO {
2164 b = -T::MIN_POSITIVE_SUBNORMAL;
2165 }
2166 ExhaustivePrimitiveFloatInclusiveRange::NotJustSpecials(
2167 specials
2168 .into_iter()
2169 .chain(exhaustive_nonzero_finite_primitive_floats_in_range(a, b)),
2170 )
2171}