malachite_base/num/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::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 ExhaustiveSignedRange::NonNegative(xs) => xs.next(),
83 ExhaustiveSignedRange::NonPositive(xs) => xs.next(),
84 ExhaustiveSignedRange::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/// ```
1014pub fn primitive_floats_increasing<T: PrimitiveFloat>() -> PrimitiveFloatIncreasingRange<T> {
1015 primitive_float_increasing_inclusive_range(T::NEGATIVE_INFINITY, T::INFINITY)
1016}
1017
1018/// Generates all finite positive primitive floats with a specified `sci_exponent` and precision.
1019///
1020/// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent_and_precision`]; see
1021/// its documentation for more.
1022#[derive(Clone, Debug, Default)]
1023pub struct ConstantPrecisionPrimitiveFloats<T: PrimitiveFloat> {
1024 phantom: PhantomData<*const T>,
1025 n: u64,
1026 increment: u64,
1027 i: u64,
1028 count: u64,
1029}
1030
1031impl<T: PrimitiveFloat> Iterator for ConstantPrecisionPrimitiveFloats<T> {
1032 type Item = T;
1033
1034 fn next(&mut self) -> Option<T> {
1035 if self.i == self.count {
1036 None
1037 } else {
1038 let out = T::from_bits(self.n);
1039 self.i += 1;
1040 if self.i < self.count {
1041 self.n += self.increment;
1042 }
1043 Some(out)
1044 }
1045 }
1046}
1047
1048/// Generates all finite positive primitive floats with a specified `sci_exponent` and precision.
1049///
1050/// Positive and negative zero are both excluded.
1051///
1052/// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s
1053/// < 2$ and $e_s$ is an integer; then $e_s$ is the sci-exponent. An integer $e_s$ occurs as the
1054/// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$.
1055///
1056/// In the above equation, $m$ is a dyadic rational. Let $p$ be the smallest integer such that
1057/// $m2^{p-1}$ is an integer. Then $p$ is the float's precision. It is also the number of
1058/// significant bits.
1059///
1060/// For example, consider the float $100.0$. It may be written as $\frac{25}{16}2^6$, so
1061/// $m=\frac{25}{16}$ and $e=6$. We can write $m$ in binary as $1.1001_2$. Thus, the sci-exponent is
1062/// 6 and the precision is 5.
1063///
1064/// If $p$ is 1, the output length is 1; otherwise, it is $2^{p-2}$.
1065///
1066/// # Complexity per iteration
1067/// Constant time and additional memory.
1068///
1069/// # Panics
1070/// Panics if the sci-exponent is less than
1071/// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than
1072/// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT), or if the precision is
1073/// zero or too large for the given sci-exponent (this can be checked using
1074/// [`max_precision_for_sci_exponent`](super::basic::floats::PrimitiveFloat::max_precision_for_sci_exponent)).
1075///
1076/// # Examples
1077/// ```
1078/// use itertools::Itertools;
1079/// use malachite_base::num::exhaustive::*;
1080/// use malachite_base::num::float::NiceFloat;
1081///
1082/// assert_eq!(
1083/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(0, 3)
1084/// .map(NiceFloat)
1085/// .collect_vec(),
1086/// [1.25, 1.75].iter().copied().map(NiceFloat).collect_vec()
1087/// );
1088/// assert_eq!(
1089/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(0, 5)
1090/// .map(NiceFloat)
1091/// .collect_vec(),
1092/// [1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375]
1093/// .iter()
1094/// .copied()
1095/// .map(NiceFloat)
1096/// .collect_vec()
1097/// );
1098/// assert_eq!(
1099/// exhaustive_primitive_floats_with_sci_exponent_and_precision::<f32>(6, 5)
1100/// .map(NiceFloat)
1101/// .collect_vec(),
1102/// [68.0, 76.0, 84.0, 92.0, 100.0, 108.0, 116.0, 124.0]
1103/// .iter()
1104/// .copied()
1105/// .map(NiceFloat)
1106/// .collect_vec()
1107/// );
1108/// ```
1109pub fn exhaustive_primitive_floats_with_sci_exponent_and_precision<T: PrimitiveFloat>(
1110 sci_exponent: i64,
1111 precision: u64,
1112) -> ConstantPrecisionPrimitiveFloats<T> {
1113 assert!(sci_exponent >= T::MIN_EXPONENT);
1114 assert!(sci_exponent <= T::MAX_EXPONENT);
1115 assert_ne!(precision, 0);
1116 let max_precision = T::max_precision_for_sci_exponent(sci_exponent);
1117 assert!(precision <= max_precision);
1118 let increment = u64::power_of_2(max_precision - precision + 1);
1119 let first_mantissa = if precision == 1 {
1120 1
1121 } else {
1122 u64::power_of_2(precision - 1) | 1
1123 };
1124 let first = T::from_integer_mantissa_and_exponent(
1125 first_mantissa,
1126 sci_exponent - i64::exact_from(precision) + 1,
1127 )
1128 .unwrap()
1129 .to_bits();
1130 let count = if precision == 1 {
1131 1
1132 } else {
1133 u64::power_of_2(precision - 2)
1134 };
1135 ConstantPrecisionPrimitiveFloats {
1136 phantom: PhantomData,
1137 n: first,
1138 increment,
1139 i: 0,
1140 count,
1141 }
1142}
1143
1144#[derive(Clone, Debug)]
1145struct PrimitiveFloatsWithExponentGenerator<T: PrimitiveFloat> {
1146 phantom: PhantomData<*const T>,
1147 sci_exponent: i64,
1148}
1149
1150impl<T: PrimitiveFloat>
1151 ExhaustiveDependentPairsYsGenerator<u64, T, ConstantPrecisionPrimitiveFloats<T>>
1152 for PrimitiveFloatsWithExponentGenerator<T>
1153{
1154 #[inline]
1155 fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats<T> {
1156 exhaustive_primitive_floats_with_sci_exponent_and_precision(self.sci_exponent, precision)
1157 }
1158}
1159
1160#[inline]
1161fn exhaustive_primitive_floats_with_sci_exponent_helper<T: PrimitiveFloat>(
1162 sci_exponent: i64,
1163) -> LexDependentPairs<
1164 u64,
1165 T,
1166 PrimitiveFloatsWithExponentGenerator<T>,
1167 PrimitiveIntIncreasingRange<u64>,
1168 ConstantPrecisionPrimitiveFloats<T>,
1169> {
1170 lex_dependent_pairs(
1171 primitive_int_increasing_inclusive_range(
1172 1,
1173 T::max_precision_for_sci_exponent(sci_exponent),
1174 ),
1175 PrimitiveFloatsWithExponentGenerator {
1176 phantom: PhantomData,
1177 sci_exponent,
1178 },
1179 )
1180}
1181
1182/// Generates all positive finite primitive floats with a specified `sci_exponent`.
1183///
1184/// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent`]; see its
1185/// documentation for more.
1186#[derive(Clone, Debug)]
1187pub struct ExhaustivePrimitiveFloatsWithExponent<T: PrimitiveFloat>(
1188 LexDependentPairs<
1189 u64,
1190 T,
1191 PrimitiveFloatsWithExponentGenerator<T>,
1192 PrimitiveIntIncreasingRange<u64>,
1193 ConstantPrecisionPrimitiveFloats<T>,
1194 >,
1195);
1196
1197impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatsWithExponent<T> {
1198 type Item = T;
1199
1200 #[inline]
1201 fn next(&mut self) -> Option<T> {
1202 self.0.next().map(|p| p.1)
1203 }
1204}
1205
1206/// Generates all positive finite primitive floats with a specified sci-exponent.
1207///
1208/// Positive and negative zero are both excluded.
1209///
1210/// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s
1211/// < 2$ and $e_s$ is an integer; then $e$ is the sci-exponent. An integer $e_s$ occurs as the
1212/// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$.
1213///
1214/// If $e_s \geq 2-2^{E-1}$ (the float is normal), the output length is $2^M$.
1215/// - For [`f32`], this is $2^{23}$, or 8388608.
1216/// - For [`f64`], this is $2^{52}$, or 4503599627370496.
1217///
1218/// If $e_s < 2-2^{E-1}$ (the float is subnormal), the output length is $2^{e_s+2^{E-1}+M-2}$.
1219/// - For [`f32`], this is $2^{e_s+149}$.
1220/// - For [`f64`], this is $2^{e_s+1074}$.
1221///
1222/// # Complexity per iteration
1223/// Constant time and additional memory.
1224///
1225/// # Panics
1226/// Panics if the sci-exponent is less than
1227/// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than
1228/// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT).
1229///
1230/// # Examples
1231/// ```
1232/// use itertools::Itertools;
1233/// use malachite_base::iterators::prefix_to_string;
1234/// use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent;
1235/// use malachite_base::num::float::NiceFloat;
1236///
1237/// assert_eq!(
1238/// prefix_to_string(
1239/// exhaustive_primitive_floats_with_sci_exponent::<f32>(0).map(NiceFloat),
1240/// 20
1241/// ),
1242/// "[1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, \
1243/// 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, ...]",
1244/// );
1245/// assert_eq!(
1246/// prefix_to_string(
1247/// exhaustive_primitive_floats_with_sci_exponent::<f32>(4).map(NiceFloat),
1248/// 20
1249/// ),
1250/// "[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, \
1251/// 29.0, 31.0, 16.5, 17.5, 18.5, 19.5, ...]"
1252/// );
1253/// assert_eq!(
1254/// exhaustive_primitive_floats_with_sci_exponent::<f32>(-147)
1255/// .map(NiceFloat)
1256/// .collect_vec(),
1257/// [6.0e-45, 8.0e-45, 7.0e-45, 1.0e-44]
1258/// .iter()
1259/// .copied()
1260/// .map(NiceFloat)
1261/// .collect_vec()
1262/// );
1263/// ```
1264#[inline]
1265pub fn exhaustive_primitive_floats_with_sci_exponent<T: PrimitiveFloat>(
1266 sci_exponent: i64,
1267) -> ExhaustivePrimitiveFloatsWithExponent<T> {
1268 ExhaustivePrimitiveFloatsWithExponent(exhaustive_primitive_floats_with_sci_exponent_helper(
1269 sci_exponent,
1270 ))
1271}
1272
1273#[derive(Clone, Debug)]
1274struct ExhaustivePositiveFinitePrimitiveFloatsGenerator<T: PrimitiveFloat> {
1275 phantom: PhantomData<*const T>,
1276}
1277
1278impl<T: PrimitiveFloat>
1279 ExhaustiveDependentPairsYsGenerator<i64, T, ExhaustivePrimitiveFloatsWithExponent<T>>
1280 for ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>
1281{
1282 #[inline]
1283 fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponent<T> {
1284 exhaustive_primitive_floats_with_sci_exponent(sci_exponent)
1285 }
1286}
1287
1288#[inline]
1289fn exhaustive_positive_finite_primitive_floats_helper<T: PrimitiveFloat>()
1290-> ExhaustiveDependentPairs<
1291 i64,
1292 T,
1293 RulerSequence<usize>,
1294 ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>,
1295 ExhaustiveSignedRange<i64>,
1296 ExhaustivePrimitiveFloatsWithExponent<T>,
1297> {
1298 exhaustive_dependent_pairs(
1299 ruler_sequence(),
1300 exhaustive_signed_inclusive_range(T::MIN_EXPONENT, T::MAX_EXPONENT),
1301 ExhaustivePositiveFinitePrimitiveFloatsGenerator {
1302 phantom: PhantomData,
1303 },
1304 )
1305}
1306
1307/// Generates all positive finite primitive floats.
1308///
1309/// This `struct` is created by [`exhaustive_positive_finite_primitive_floats`]; see its
1310/// documentation for more.
1311#[derive(Clone, Debug)]
1312pub struct ExhaustivePositiveFinitePrimitiveFloats<T: PrimitiveFloat>(
1313 ExhaustiveDependentPairs<
1314 i64,
1315 T,
1316 RulerSequence<usize>,
1317 ExhaustivePositiveFinitePrimitiveFloatsGenerator<T>,
1318 ExhaustiveSignedRange<i64>,
1319 ExhaustivePrimitiveFloatsWithExponent<T>,
1320 >,
1321);
1322
1323impl<T: PrimitiveFloat> Iterator for ExhaustivePositiveFinitePrimitiveFloats<T> {
1324 type Item = T;
1325
1326 #[inline]
1327 fn next(&mut self) -> Option<T> {
1328 self.0.next().map(|p| p.1)
1329 }
1330}
1331
1332/// Generates all positive finite primitive floats.
1333///
1334/// Positive and negative zero are both excluded.
1335///
1336/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1337/// ascending order instead, use [`positive_finite_primitive_floats_increasing`].
1338///
1339/// The output length is $2^M(2^E-1)-1$.
1340/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
1341/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
1342///
1343/// # Complexity per iteration
1344/// Constant time and additional memory.
1345///
1346/// # Examples
1347/// ```
1348/// use malachite_base::iterators::prefix_to_string;
1349/// use malachite_base::num::exhaustive::exhaustive_positive_finite_primitive_floats;
1350/// use malachite_base::num::float::NiceFloat;
1351///
1352/// assert_eq!(
1353/// prefix_to_string(
1354/// exhaustive_positive_finite_primitive_floats::<f32>().map(NiceFloat),
1355/// 50
1356/// ),
1357/// "[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, \
1358/// 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, \
1359/// 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, \
1360/// 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ...]"
1361/// );
1362/// ```
1363#[inline]
1364pub fn exhaustive_positive_finite_primitive_floats<T: PrimitiveFloat>()
1365-> ExhaustivePositiveFinitePrimitiveFloats<T> {
1366 ExhaustivePositiveFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats_helper())
1367}
1368
1369/// Generates all negative finite primitive floats.
1370///
1371/// This `struct` is created by [`exhaustive_negative_finite_primitive_floats`]; see its
1372/// documentation for more.
1373#[derive(Clone, Debug)]
1374pub struct ExhaustiveNegativeFinitePrimitiveFloats<T: PrimitiveFloat>(
1375 ExhaustivePositiveFinitePrimitiveFloats<T>,
1376);
1377
1378impl<T: PrimitiveFloat> Iterator for ExhaustiveNegativeFinitePrimitiveFloats<T> {
1379 type Item = T;
1380
1381 #[inline]
1382 fn next(&mut self) -> Option<T> {
1383 self.0.next().map(|f| -f)
1384 }
1385}
1386
1387/// Generates all negative finite primitive floats.
1388///
1389/// Positive and negative zero are both excluded.
1390///
1391/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1392/// ascending order instead, use [`negative_finite_primitive_floats_increasing`].
1393///
1394/// The output length is $2^M(2^E-1)-1$.
1395/// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039.
1396/// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311.
1397///
1398/// # Complexity per iteration
1399/// Constant time and additional memory.
1400///
1401/// # Examples
1402/// ```
1403/// use malachite_base::iterators::prefix_to_string;
1404/// use malachite_base::num::exhaustive::exhaustive_negative_finite_primitive_floats;
1405/// use malachite_base::num::float::NiceFloat;
1406///
1407/// assert_eq!(
1408/// prefix_to_string(
1409/// exhaustive_negative_finite_primitive_floats::<f32>().map(NiceFloat),
1410/// 50
1411/// ),
1412/// "[-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, \
1413/// -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, \
1414/// -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, \
1415/// -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, \
1416/// -1.40625, -2.875, -1.46875, -0.375, -1.53125, -3.125, ...]"
1417/// );
1418/// ```
1419#[inline]
1420pub fn exhaustive_negative_finite_primitive_floats<T: PrimitiveFloat>()
1421-> ExhaustiveNegativeFinitePrimitiveFloats<T> {
1422 ExhaustiveNegativeFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats())
1423}
1424
1425/// Generates all nonzero finite primitive floats.
1426///
1427/// This `struct` is created by [`exhaustive_nonzero_finite_primitive_floats`]; see its
1428/// documentation for more.
1429#[derive(Clone, Debug)]
1430pub struct ExhaustiveNonzeroFinitePrimitiveFloats<T: PrimitiveFloat> {
1431 toggle: bool,
1432 xs: ExhaustivePositiveFinitePrimitiveFloats<T>,
1433 x: T,
1434}
1435
1436impl<T: PrimitiveFloat> Iterator for ExhaustiveNonzeroFinitePrimitiveFloats<T> {
1437 type Item = T;
1438
1439 #[inline]
1440 fn next(&mut self) -> Option<T> {
1441 self.toggle.not_assign();
1442 Some(if self.toggle {
1443 self.x = self.xs.next().unwrap();
1444 self.x
1445 } else {
1446 -self.x
1447 })
1448 }
1449}
1450
1451/// Generates all nonzero finite primitive floats.
1452///
1453/// Positive and negative zero are both excluded.
1454///
1455/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1456/// ascending order instead, use [`nonzero_finite_primitive_floats_increasing`].
1457///
1458/// The output length is $2^{M+1}(2^E-1)-2$.
1459/// - For [`f32`], this is $2^{32}-2^{24}-2$, or 4278190078.
1460/// - For [`f64`], this is $2^{64}-2^{53}-2$, or 18437736874454810622.
1461///
1462/// # Complexity per iteration
1463/// Constant time and additional memory.
1464///
1465/// # Examples
1466/// ```
1467/// use malachite_base::iterators::prefix_to_string;
1468/// use malachite_base::num::exhaustive::exhaustive_nonzero_finite_primitive_floats;
1469/// use malachite_base::num::float::NiceFloat;
1470///
1471/// assert_eq!(
1472/// prefix_to_string(
1473/// exhaustive_nonzero_finite_primitive_floats::<f32>().map(NiceFloat),
1474/// 50
1475/// ),
1476/// "[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, \
1477/// -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, \
1478/// 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, \
1479/// 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ...]"
1480/// );
1481/// ```
1482#[inline]
1483pub fn exhaustive_nonzero_finite_primitive_floats<T: PrimitiveFloat>()
1484-> ExhaustiveNonzeroFinitePrimitiveFloats<T> {
1485 ExhaustiveNonzeroFinitePrimitiveFloats {
1486 toggle: false,
1487 xs: exhaustive_positive_finite_primitive_floats(),
1488 x: T::ZERO,
1489 }
1490}
1491
1492pub type ExhaustiveFinitePrimitiveFloats<T> =
1493 Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>>;
1494
1495/// Generates all finite primitive floats.
1496///
1497/// Positive and negative zero are both included.
1498///
1499/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1500/// ascending order instead, use [`finite_primitive_floats_increasing`].
1501///
1502/// The output length is $2^{M+1}(2^E-1)$.
1503/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
1504/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
1505///
1506/// # Complexity per iteration
1507/// Constant time and additional memory.
1508///
1509/// # Examples
1510/// ```
1511/// use malachite_base::iterators::prefix_to_string;
1512/// use malachite_base::num::exhaustive::exhaustive_finite_primitive_floats;
1513/// use malachite_base::num::float::NiceFloat;
1514///
1515/// assert_eq!(
1516/// prefix_to_string(
1517/// exhaustive_finite_primitive_floats::<f32>().map(NiceFloat),
1518/// 50
1519/// ),
1520/// "[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, \
1521/// -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, \
1522/// 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, \
1523/// 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ...]"
1524/// );
1525/// ```
1526#[inline]
1527pub fn exhaustive_finite_primitive_floats<T: PrimitiveFloat>()
1528-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1529 ::alloc::vec![T::ZERO, T::NEGATIVE_ZERO]
1530 .into_iter()
1531 .chain(exhaustive_nonzero_finite_primitive_floats())
1532}
1533
1534/// Generates all positive primitive floats.
1535///
1536/// Positive and negative zero are both excluded.
1537///
1538/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1539/// ascending order instead, use [`positive_primitive_floats_increasing`].
1540///
1541/// The output length is $2^M(2^E-1)$.
1542/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
1543/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
1544///
1545/// # Complexity per iteration
1546/// Constant time and additional memory.
1547///
1548/// # Examples
1549/// ```
1550/// use malachite_base::iterators::prefix_to_string;
1551/// use malachite_base::num::exhaustive::exhaustive_positive_primitive_floats;
1552/// use malachite_base::num::float::NiceFloat;
1553///
1554/// assert_eq!(
1555/// prefix_to_string(
1556/// exhaustive_positive_primitive_floats::<f32>().map(NiceFloat),
1557/// 50
1558/// ),
1559/// "[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, \
1560/// 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, \
1561/// 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, \
1562/// 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, \
1563/// 1.53125, ...]"
1564/// );
1565/// ```
1566#[inline]
1567pub fn exhaustive_positive_primitive_floats<T: PrimitiveFloat>()
1568-> Chain<Once<T>, ExhaustivePositiveFinitePrimitiveFloats<T>> {
1569 once(T::INFINITY).chain(exhaustive_positive_finite_primitive_floats())
1570}
1571
1572/// Generates all negative primitive floats.
1573///
1574/// Positive and negative zero are both excluded.
1575///
1576/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1577/// ascending order instead, use [`negative_primitive_floats_increasing`].
1578///
1579/// The output length is $2^M(2^E-1)$.
1580/// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040.
1581/// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312.
1582///
1583/// # Complexity per iteration
1584/// Constant time and additional memory.
1585///
1586/// # Examples
1587/// ```
1588/// use malachite_base::iterators::prefix_to_string;
1589/// use malachite_base::num::exhaustive::exhaustive_negative_primitive_floats;
1590/// use malachite_base::num::float::NiceFloat;
1591///
1592/// assert_eq!(
1593/// prefix_to_string(
1594/// exhaustive_negative_primitive_floats::<f32>().map(NiceFloat),
1595/// 50
1596/// ),
1597/// "[-Infinity, -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, \
1598/// -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, \
1599/// -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, \
1600/// -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, \
1601/// -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, ...]"
1602/// );
1603/// ```
1604#[inline]
1605pub fn exhaustive_negative_primitive_floats<T: PrimitiveFloat>()
1606-> Chain<Once<T>, ExhaustiveNegativeFinitePrimitiveFloats<T>> {
1607 once(T::NEGATIVE_INFINITY).chain(exhaustive_negative_finite_primitive_floats())
1608}
1609
1610/// Generates all nonzero primitive floats.
1611///
1612/// Positive and negative zero are both excluded. NaN is excluded as well.
1613///
1614/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in
1615/// ascending order instead, use [`nonzero_primitive_floats_increasing`].
1616///
1617/// The output length is $2^{M+1}(2^E-1)$.
1618/// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080.
1619/// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624.
1620///
1621/// # Complexity per iteration
1622/// Constant time and additional memory.
1623///
1624/// # Examples
1625/// ```
1626/// use malachite_base::iterators::prefix_to_string;
1627/// use malachite_base::num::exhaustive::exhaustive_nonzero_primitive_floats;
1628/// use malachite_base::num::float::NiceFloat;
1629///
1630/// assert_eq!(
1631/// prefix_to_string(
1632/// exhaustive_nonzero_primitive_floats::<f32>().map(NiceFloat),
1633/// 50
1634/// ),
1635/// "[Infinity, -Infinity, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, \
1636/// -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, \
1637/// 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, \
1638/// 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, \
1639/// ...]"
1640/// );
1641/// ```
1642#[inline]
1643pub fn exhaustive_nonzero_primitive_floats<T: PrimitiveFloat>()
1644-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1645 ::alloc::vec![T::INFINITY, T::NEGATIVE_INFINITY]
1646 .into_iter()
1647 .chain(exhaustive_nonzero_finite_primitive_floats())
1648}
1649
1650/// Generates all primitive floats.
1651///
1652/// Positive and negative zero are both included.
1653///
1654/// Roughly speaking, the simplest floats are generated first. If you want to generate the floats
1655/// (except `NaN`) in ascending order instead, use [`primitive_floats_increasing`].
1656///
1657/// The output length is $2^{M+1}(2^E-1)+2$.
1658/// - For [`f32`], this is $2^{32}-2^{24}+2$, or 4278190082.
1659/// - For [`f64`], this is $2^{64}-2^{53}+2$, or 18437736874454810626.
1660///
1661/// # Complexity per iteration
1662/// Constant time and additional memory.
1663///
1664/// # Examples
1665/// ```
1666/// use malachite_base::iterators::prefix_to_string;
1667/// use malachite_base::num::exhaustive::exhaustive_primitive_floats;
1668/// use malachite_base::num::float::NiceFloat;
1669///
1670/// assert_eq!(
1671/// prefix_to_string(exhaustive_primitive_floats::<f32>().map(NiceFloat), 50),
1672/// "[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, \
1673/// -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, \
1674/// -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, \
1675/// -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, ...]"
1676/// );
1677/// ```
1678#[inline]
1679pub fn exhaustive_primitive_floats<T: PrimitiveFloat>()
1680-> Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloats<T>> {
1681 ::alloc::vec![T::NAN, T::INFINITY, T::NEGATIVE_INFINITY, T::ZERO, T::NEGATIVE_ZERO]
1682 .into_iter()
1683 .chain(exhaustive_nonzero_finite_primitive_floats())
1684}
1685
1686pub_test! {exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range<T: PrimitiveFloat>(
1687 a: T,
1688 b: T,
1689 sci_exponent: i64,
1690 precision: u64
1691) -> ConstantPrecisionPrimitiveFloats<T> {
1692 assert!(a.is_finite());
1693 assert!(b.is_finite());
1694 assert!(a > T::ZERO);
1695 assert!(b > T::ZERO);
1696 assert!(sci_exponent >= T::MIN_EXPONENT);
1697 assert!(sci_exponent <= T::MAX_EXPONENT);
1698 let (am, ae) = a.raw_mantissa_and_exponent();
1699 let (bm, be) = b.raw_mantissa_and_exponent();
1700 let ae_actual_sci_exponent = if ae == 0 {
1701 i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1
1702 } else {
1703 i64::wrapping_from(ae) - T::MAX_EXPONENT
1704 };
1705 let be_actual_sci_exponent = if be == 0 {
1706 i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1
1707 } else {
1708 i64::wrapping_from(be) - T::MAX_EXPONENT
1709 };
1710 assert_eq!(ae_actual_sci_exponent, sci_exponent);
1711 assert_eq!(be_actual_sci_exponent, sci_exponent);
1712 assert!(am <= bm);
1713 assert_ne!(precision, 0);
1714 let max_precision = T::max_precision_for_sci_exponent(sci_exponent);
1715 assert!(precision <= max_precision);
1716 if precision == 1 && am == 0 {
1717 return ConstantPrecisionPrimitiveFloats {
1718 phantom: PhantomData,
1719 n: a.to_bits(),
1720 increment: 0,
1721 i: 0,
1722 count: 1,
1723 };
1724 }
1725 let trailing_zeros = max_precision - precision;
1726 let increment = u64::power_of_2(trailing_zeros + 1);
1727 let mut start_mantissa = am.round_to_multiple_of_power_of_2(trailing_zeros, Up).0;
1728 if !start_mantissa.get_bit(trailing_zeros) {
1729 start_mantissa.set_bit(trailing_zeros);
1730 }
1731 if start_mantissa > bm {
1732 return ConstantPrecisionPrimitiveFloats::default();
1733 }
1734 let mut end_mantissa = bm.round_to_multiple_of_power_of_2(trailing_zeros, Down).0;
1735 if !end_mantissa.get_bit(trailing_zeros) {
1736 let adjust = u64::power_of_2(trailing_zeros);
1737 if adjust > end_mantissa {
1738 return ConstantPrecisionPrimitiveFloats::default();
1739 }
1740 end_mantissa -= adjust;
1741 }
1742 assert!(start_mantissa <= end_mantissa);
1743 let count = ((end_mantissa - start_mantissa) >> (trailing_zeros + 1)) + 1;
1744 let first = T::from_raw_mantissa_and_exponent(start_mantissa, ae).to_bits();
1745 ConstantPrecisionPrimitiveFloats {
1746 phantom: PhantomData,
1747 n: first,
1748 increment,
1749 i: 0,
1750 count,
1751 }
1752}}
1753
1754#[derive(Clone, Debug)]
1755struct PrimitiveFloatsWithExponentInRangeGenerator<T: PrimitiveFloat> {
1756 a: T,
1757 b: T,
1758 sci_exponent: i64,
1759 phantom: PhantomData<*const T>,
1760}
1761
1762impl<T: PrimitiveFloat>
1763 ExhaustiveDependentPairsYsGenerator<u64, T, ConstantPrecisionPrimitiveFloats<T>>
1764 for PrimitiveFloatsWithExponentInRangeGenerator<T>
1765{
1766 #[inline]
1767 fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats<T> {
1768 exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range(
1769 self.a,
1770 self.b,
1771 self.sci_exponent,
1772 precision,
1773 )
1774 }
1775}
1776
1777#[inline]
1778fn exhaustive_primitive_floats_with_sci_exponent_in_range_helper<T: PrimitiveFloat>(
1779 a: T,
1780 b: T,
1781 sci_exponent: i64,
1782) -> LexDependentPairs<
1783 u64,
1784 T,
1785 PrimitiveFloatsWithExponentInRangeGenerator<T>,
1786 PrimitiveIntIncreasingRange<u64>,
1787 ConstantPrecisionPrimitiveFloats<T>,
1788> {
1789 lex_dependent_pairs(
1790 primitive_int_increasing_inclusive_range(
1791 1,
1792 T::max_precision_for_sci_exponent(sci_exponent),
1793 ),
1794 PrimitiveFloatsWithExponentInRangeGenerator {
1795 a,
1796 b,
1797 sci_exponent,
1798 phantom: PhantomData,
1799 },
1800 )
1801}
1802
1803#[doc(hidden)]
1804#[derive(Clone, Debug)]
1805pub struct ExhaustivePrimitiveFloatsWithExponentInRange<T: PrimitiveFloat>(
1806 LexDependentPairs<
1807 u64,
1808 T,
1809 PrimitiveFloatsWithExponentInRangeGenerator<T>,
1810 PrimitiveIntIncreasingRange<u64>,
1811 ConstantPrecisionPrimitiveFloats<T>,
1812 >,
1813);
1814
1815impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1816 type Item = T;
1817
1818 #[inline]
1819 fn next(&mut self) -> Option<T> {
1820 self.0.next().map(|p| p.1)
1821 }
1822}
1823
1824#[doc(hidden)]
1825#[inline]
1826pub fn exhaustive_primitive_floats_with_sci_exponent_in_range<T: PrimitiveFloat>(
1827 a: T,
1828 b: T,
1829 sci_exponent: i64,
1830) -> ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1831 ExhaustivePrimitiveFloatsWithExponentInRange(
1832 exhaustive_primitive_floats_with_sci_exponent_in_range_helper(a, b, sci_exponent),
1833 )
1834}
1835
1836#[derive(Clone, Debug)]
1837struct ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T: PrimitiveFloat> {
1838 a: T,
1839 b: T,
1840 a_sci_exponent: i64,
1841 b_sci_exponent: i64,
1842 phantom: PhantomData<*const T>,
1843}
1844
1845impl<T: PrimitiveFloat>
1846 ExhaustiveDependentPairsYsGenerator<i64, T, ExhaustivePrimitiveFloatsWithExponentInRange<T>>
1847 for ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>
1848{
1849 #[inline]
1850 fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponentInRange<T> {
1851 let a = if sci_exponent == self.a_sci_exponent {
1852 self.a
1853 } else {
1854 T::from_integer_mantissa_and_exponent(1, sci_exponent).unwrap()
1855 };
1856 let b = if sci_exponent == self.b_sci_exponent {
1857 self.b
1858 } else {
1859 T::from_integer_mantissa_and_exponent(1, sci_exponent + 1)
1860 .unwrap()
1861 .next_lower()
1862 };
1863 exhaustive_primitive_floats_with_sci_exponent_in_range(a, b, sci_exponent)
1864 }
1865}
1866
1867#[inline]
1868fn exhaustive_positive_finite_primitive_floats_in_range_helper<T: PrimitiveFloat>(
1869 a: T,
1870 b: T,
1871) -> ExhaustiveDependentPairs<
1872 i64,
1873 T,
1874 RulerSequence<usize>,
1875 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>,
1876 ExhaustiveSignedRange<i64>,
1877 ExhaustivePrimitiveFloatsWithExponentInRange<T>,
1878> {
1879 assert!(a.is_finite());
1880 assert!(b.is_finite());
1881 assert!(a > T::ZERO);
1882 assert!(a <= b);
1883 let (am, ae) = a.raw_mantissa_and_exponent();
1884 let (bm, be) = b.raw_mantissa_and_exponent();
1885 let a_sci_exponent = if ae == 0 {
1886 i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1
1887 } else {
1888 i64::wrapping_from(ae) - T::MAX_EXPONENT
1889 };
1890 let b_sci_exponent = if be == 0 {
1891 i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1
1892 } else {
1893 i64::wrapping_from(be) - T::MAX_EXPONENT
1894 };
1895 exhaustive_dependent_pairs(
1896 ruler_sequence(),
1897 exhaustive_signed_inclusive_range(a_sci_exponent, b_sci_exponent),
1898 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator {
1899 a,
1900 b,
1901 a_sci_exponent,
1902 b_sci_exponent,
1903 phantom: PhantomData,
1904 },
1905 )
1906}
1907
1908#[doc(hidden)]
1909#[derive(Clone, Debug)]
1910pub struct ExhaustivePositiveFinitePrimitiveFloatsInRange<T: PrimitiveFloat>(
1911 ExhaustiveDependentPairs<
1912 i64,
1913 T,
1914 RulerSequence<usize>,
1915 ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator<T>,
1916 ExhaustiveSignedRange<i64>,
1917 ExhaustivePrimitiveFloatsWithExponentInRange<T>,
1918 >,
1919);
1920
1921impl<T: PrimitiveFloat> Iterator for ExhaustivePositiveFinitePrimitiveFloatsInRange<T> {
1922 type Item = T;
1923
1924 #[inline]
1925 fn next(&mut self) -> Option<T> {
1926 self.0.next().map(|p| p.1)
1927 }
1928}
1929
1930#[doc(hidden)]
1931#[inline]
1932pub fn exhaustive_positive_finite_primitive_floats_in_range<T: PrimitiveFloat>(
1933 a: T,
1934 b: T,
1935) -> ExhaustivePositiveFinitePrimitiveFloatsInRange<T> {
1936 ExhaustivePositiveFinitePrimitiveFloatsInRange(
1937 exhaustive_positive_finite_primitive_floats_in_range_helper(a, b),
1938 )
1939}
1940
1941#[doc(hidden)]
1942#[derive(Clone, Debug)]
1943pub enum ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T: PrimitiveFloat> {
1944 AllPositive(ExhaustivePositiveFinitePrimitiveFloatsInRange<T>),
1945 AllNegative(ExhaustivePositiveFinitePrimitiveFloatsInRange<T>),
1946 PositiveAndNegative(
1947 bool,
1948 ExhaustivePositiveFinitePrimitiveFloatsInRange<T>,
1949 ExhaustivePositiveFinitePrimitiveFloatsInRange<T>,
1950 ),
1951}
1952
1953impl<T: PrimitiveFloat> Iterator for ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T> {
1954 type Item = T;
1955
1956 fn next(&mut self) -> Option<T> {
1957 match self {
1958 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllPositive(xs) => xs.next(),
1959 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllNegative(xs) => xs.next().map(T::neg),
1960 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::PositiveAndNegative(
1961 toggle,
1962 pos_xs,
1963 neg_xs,
1964 ) => {
1965 toggle.not_assign();
1966 if *toggle {
1967 pos_xs.next().or_else(|| neg_xs.next().map(T::neg))
1968 } else {
1969 neg_xs.next().map(T::neg).or_else(|| pos_xs.next())
1970 }
1971 }
1972 }
1973 }
1974}
1975
1976#[doc(hidden)]
1977#[inline]
1978pub fn exhaustive_nonzero_finite_primitive_floats_in_range<T: PrimitiveFloat>(
1979 a: T,
1980 b: T,
1981) -> ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T> {
1982 assert!(a.is_finite());
1983 assert!(b.is_finite());
1984 assert!(a != T::ZERO);
1985 assert!(b != T::ZERO);
1986 assert!(a <= b);
1987 if a > T::ZERO {
1988 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllPositive(
1989 exhaustive_positive_finite_primitive_floats_in_range(a, b),
1990 )
1991 } else if b < T::ZERO {
1992 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllNegative(
1993 exhaustive_positive_finite_primitive_floats_in_range(-b, -a),
1994 )
1995 } else {
1996 ExhaustiveNonzeroFinitePrimitiveFloatsInRange::PositiveAndNegative(
1997 false,
1998 exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, b),
1999 exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, -a),
2000 )
2001 }
2002}
2003
2004/// Generates all primitive floats in an interval.
2005///
2006/// This `enum` is created by [`exhaustive_primitive_float_range`] and
2007/// [`exhaustive_primitive_float_inclusive_range`]; see their documentation for more.
2008#[allow(clippy::large_enum_variant)]
2009#[derive(Clone, Debug)]
2010pub enum ExhaustivePrimitiveFloatInclusiveRange<T: PrimitiveFloat> {
2011 JustSpecials(IntoIter<T>),
2012 NotJustSpecials(Chain<IntoIter<T>, ExhaustiveNonzeroFinitePrimitiveFloatsInRange<T>>),
2013}
2014
2015impl<T: PrimitiveFloat> Iterator for ExhaustivePrimitiveFloatInclusiveRange<T> {
2016 type Item = T;
2017
2018 fn next(&mut self) -> Option<T> {
2019 match self {
2020 ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(xs) => xs.next(),
2021 ExhaustivePrimitiveFloatInclusiveRange::NotJustSpecials(xs) => xs.next(),
2022 }
2023 }
2024}
2025
2026/// Generates all primitive floats in the half-open interval $[a, b)$.
2027///
2028/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
2029/// than zero.
2030///
2031/// The floats are generated in a way such that simpler floats (with lower precision) are generated
2032/// first. To generate floats in ascending order instead, use [`primitive_float_increasing_range`]
2033/// instead.
2034///
2035/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
2036/// `NiceFloat(b)` are equal, the range is empty.
2037///
2038/// Let $\varphi$ be
2039/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
2040///
2041/// The output length is $\varphi(b) - \varphi(a)$.
2042///
2043/// # Complexity per iteration
2044/// Constant time and additional memory.
2045///
2046/// # Panics
2047/// Panics if `NiceFloat(a) > NiceFloat(b)`.
2048///
2049/// # Examples
2050/// ```
2051/// use malachite_base::iterators::prefix_to_string;
2052/// use malachite_base::num::exhaustive::exhaustive_primitive_float_range;
2053/// use malachite_base::num::float::NiceFloat;
2054///
2055/// assert_eq!(
2056/// prefix_to_string(
2057/// exhaustive_primitive_float_range::<f32>(core::f32::consts::E, core::f32::consts::PI)
2058/// .map(NiceFloat),
2059/// 50
2060/// ),
2061/// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \
2062/// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \
2063/// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \
2064/// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \
2065/// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \
2066/// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]"
2067/// );
2068/// ```
2069#[inline]
2070pub fn exhaustive_primitive_float_range<T: PrimitiveFloat>(
2071 a: T,
2072 b: T,
2073) -> ExhaustivePrimitiveFloatInclusiveRange<T> {
2074 assert!(!a.is_nan());
2075 assert!(!b.is_nan());
2076 assert!(NiceFloat(a) <= NiceFloat(b));
2077 if NiceFloat(a) == NiceFloat(b) {
2078 ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(Vec::new().into_iter())
2079 } else {
2080 exhaustive_primitive_float_inclusive_range(a, b.next_lower())
2081 }
2082}
2083
2084/// Generates all primitive floats in the closed interval $[a, b]$.
2085///
2086/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
2087/// than zero.
2088///
2089/// The floats are generated in a way such that simpler floats (with lower precision) are generated
2090/// first. To generate floats in ascending order instead, use
2091/// `primitive_float_increasing_inclusive_range` instead.
2092///
2093/// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and
2094/// `NiceFloat(b)` are equal, the range contains a single element.
2095///
2096/// Let $\varphi$ be
2097/// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation):
2098///
2099/// The output length is $\varphi(b) - \varphi(a) + 1$.
2100///
2101/// # Complexity per iteration
2102/// Constant time and additional memory.
2103///
2104/// # Panics
2105/// Panics if `NiceFloat(a) > NiceFloat(b)`.
2106///
2107/// # Examples
2108/// ```
2109/// use malachite_base::iterators::prefix_to_string;
2110/// use malachite_base::num::exhaustive::exhaustive_primitive_float_inclusive_range;
2111/// use malachite_base::num::float::NiceFloat;
2112///
2113/// assert_eq!(
2114/// prefix_to_string(
2115/// exhaustive_primitive_float_inclusive_range::<f32>(
2116/// core::f32::consts::E,
2117/// core::f32::consts::PI
2118/// )
2119/// .map(NiceFloat),
2120/// 50
2121/// ),
2122/// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \
2123/// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \
2124/// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \
2125/// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \
2126/// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \
2127/// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]"
2128/// );
2129/// ```
2130#[inline]
2131pub fn exhaustive_primitive_float_inclusive_range<T: PrimitiveFloat>(
2132 mut a: T,
2133 mut b: T,
2134) -> ExhaustivePrimitiveFloatInclusiveRange<T> {
2135 assert!(!a.is_nan());
2136 assert!(!b.is_nan());
2137 assert!(NiceFloat(a) <= NiceFloat(b));
2138 let mut specials = Vec::new();
2139 if b == T::INFINITY {
2140 specials.push(T::INFINITY);
2141 if a == T::INFINITY {
2142 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2143 }
2144 b = T::MAX_FINITE;
2145 }
2146 if a == T::NEGATIVE_INFINITY {
2147 specials.push(T::NEGATIVE_INFINITY);
2148 if b == T::NEGATIVE_INFINITY {
2149 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2150 }
2151 a = -T::MAX_FINITE;
2152 }
2153 if NiceFloat(a) <= NiceFloat(T::ZERO) && NiceFloat(b) >= NiceFloat(T::ZERO) {
2154 specials.push(T::ZERO);
2155 }
2156 if NiceFloat(a) <= NiceFloat(T::NEGATIVE_ZERO) && NiceFloat(b) >= NiceFloat(T::NEGATIVE_ZERO) {
2157 specials.push(T::NEGATIVE_ZERO);
2158 }
2159 if a == T::ZERO {
2160 if b == T::ZERO {
2161 return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter());
2162 }
2163 a = T::MIN_POSITIVE_SUBNORMAL;
2164 }
2165 if b == T::ZERO {
2166 b = -T::MIN_POSITIVE_SUBNORMAL;
2167 }
2168 ExhaustivePrimitiveFloatInclusiveRange::NotJustSpecials(
2169 specials
2170 .into_iter()
2171 .chain(exhaustive_nonzero_finite_primitive_floats_in_range(a, b)),
2172 )
2173}