malachite_float/conversion/
from_bits.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Float;
10use crate::InnerFloat::Finite;
11use alloc::vec;
12use core::cmp::Ordering::{self, *};
13use malachite_base::num::arithmetic::traits::{DivisibleByPowerOf2, NegModPowerOf2, PowerOf2};
14use malachite_base::num::basic::integers::PrimitiveInt;
15use malachite_base::num::logic::traits::SignificantBits;
16use malachite_base::rounding_modes::RoundingMode::{self, *};
17use malachite_nz::natural::LIMB_HIGH_BIT;
18use malachite_nz::natural::{Natural, bit_to_limb_count_ceiling};
19use malachite_nz::platform::Limb;
20
21impl Float {
22    /// Returns an approximation of a real number, given the number's bits. To avoid troublesome
23    /// edge cases, the number should not be a dyadic rational (and the iterator of bits should
24    /// therefore be infinite, and not eventually 0 or 1). Given this assumption, the rounding mode
25    /// `Exact` should never be passed.
26    ///
27    /// The approximation has precision `prec` and is rounded according to the provided rounding
28    /// mode.
29    ///
30    /// This function reads `prec + z` bits, or `prec + z + 1` bits if `rm` is `Nearest`, where `z`
31    /// is the number of leading false bits in `bits`.
32    ///
33    /// This function always produces a value in the interval $[1/2,1]$. In particular, it never
34    /// overflows or underflows.
35    ///
36    /// $$
37    /// f((x_k),p,m) = C+\varepsilon,
38    /// $$
39    /// where
40    /// $$
41    /// C=\sum_{k=0}^\infty x_k 2^{-(k+1)}.
42    /// $$
43    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 C\rfloor-p+1}$.
44    /// - If $m$ is `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 C\rfloor-p}$.
45    ///
46    /// The output has precision `prec`.
47    ///
48    /// # Worst-case complexity
49    /// $T(n) = O(n)$
50    ///
51    /// $M(n) = O(n)$
52    ///
53    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
54    ///
55    /// # Panics
56    /// Panics if `prec` is zero or `rm` is `Exact`.
57    ///
58    /// # Examples
59    /// ```
60    /// use malachite_base::rounding_modes::RoundingMode::*;
61    /// use malachite_float::Float;
62    /// use std::cmp::Ordering::*;
63    ///
64    /// // Produces 10100100010000100000...
65    /// struct Bits {
66    ///     b: bool,
67    ///     k: usize,
68    ///     j: usize,
69    /// }
70    ///
71    /// impl Iterator for Bits {
72    ///     type Item = bool;
73    ///
74    ///     fn next(&mut self) -> Option<bool> {
75    ///         Some(if self.b {
76    ///             self.b = false;
77    ///             self.j = self.k;
78    ///             true
79    ///         } else {
80    ///             self.j -= 1;
81    ///             if self.j == 0 {
82    ///                 self.k += 1;
83    ///                 self.b = true;
84    ///             }
85    ///             false
86    ///         })
87    ///     }
88    /// }
89    ///
90    /// impl Bits {
91    ///     fn new() -> Bits {
92    ///         Bits {
93    ///             b: true,
94    ///             k: 1,
95    ///             j: 1,
96    ///         }
97    ///     }
98    /// }
99    ///
100    /// let (c, o) = Float::non_dyadic_from_bits_prec_round(Bits::new(), 100, Floor);
101    /// assert_eq!(c.to_string(), "0.6416325606551538662938427702254");
102    /// assert_eq!(o, Less);
103    ///
104    /// let (c, o) = Float::non_dyadic_from_bits_prec_round(Bits::new(), 100, Ceiling);
105    /// assert_eq!(c.to_string(), "0.641632560655153866293842770226");
106    /// assert_eq!(o, Greater);
107    /// ```
108    pub fn non_dyadic_from_bits_prec_round<I: Iterator<Item = bool>>(
109        mut bits: I,
110        prec: u64,
111        rm: RoundingMode,
112    ) -> (Self, Ordering) {
113        assert_ne!(prec, 0);
114        assert_ne!(rm, Exact);
115        let len = bit_to_limb_count_ceiling(prec);
116        let mut limbs = vec![0; len];
117        let mut limbs_it = limbs.iter_mut().rev();
118        let mut x = limbs_it.next().unwrap();
119        let mut mask = LIMB_HIGH_BIT;
120        let mut seen_one = false;
121        let mut exponent: i32 = 0;
122        let mut remaining = prec;
123        for b in &mut bits {
124            if !seen_one {
125                if b {
126                    seen_one = true;
127                } else {
128                    exponent = exponent.checked_sub(1).unwrap();
129                    continue;
130                }
131            }
132            if b {
133                *x |= mask;
134            }
135            remaining -= 1;
136            if remaining == 0 {
137                break;
138            }
139            if mask == 1 {
140                x = limbs_it.next().unwrap();
141                mask = LIMB_HIGH_BIT;
142            } else {
143                mask >>= 1;
144            }
145        }
146        let mut significand = Natural::from_owned_limbs_asc(limbs);
147        let increment = rm == Up || rm == Ceiling || (rm == Nearest && bits.next() == Some(true));
148        if increment {
149            significand +=
150                Natural::from(Limb::power_of_2(prec.neg_mod_power_of_2(Limb::LOG_WIDTH)));
151            if !significand
152                .significant_bits()
153                .divisible_by_power_of_2(Limb::LOG_WIDTH)
154            {
155                significand >>= 1;
156                exponent += 1;
157            }
158        }
159        (
160            Self(Finite {
161                sign: true,
162                exponent,
163                precision: prec,
164                significand,
165            }),
166            if increment { Greater } else { Less },
167        )
168    }
169
170    /// Returns an approximation of a real number, given the number's bits. To avoid troublesome
171    /// edge cases, the number should not be a dyadic rational (and the iterator of bits should
172    /// therefore be infinite, and not eventually 0 or 1).
173    ///
174    /// The approximation has precision `prec` and is rounded according to the `Nearest` rounding
175    /// mode.
176    ///
177    /// This function reads `prec + z + 1` bits, where `z` is the number of leading false bits in
178    /// `bits`.
179    ///
180    /// This function always produces a value in the interval $[1/2,1]$. In particular, it never
181    /// overflows or underflows.
182    ///
183    /// $$
184    /// f((x_k),p,m) = C+\varepsilon,
185    /// $$
186    /// where
187    /// $$
188    /// C=\sum_{k=0}^\infty x_k 2^{-(k+1)}
189    /// $$
190    /// and $|\varepsilon| < 2^{\lfloor\log_2 C\rfloor-p}$.
191    ///
192    /// The output has precision `prec`.
193    ///
194    /// # Worst-case complexity
195    /// $T(n) = O(n)$
196    ///
197    /// $M(n) = O(n)$
198    ///
199    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
200    ///
201    /// # Panics
202    /// Panics if `prec` is zero.
203    ///
204    /// # Examples
205    /// ```
206    /// use malachite_float::Float;
207    /// use std::cmp::Ordering::*;
208    ///
209    /// // Produces 10100100010000100000...
210    /// struct Bits {
211    ///     b: bool,
212    ///     k: usize,
213    ///     j: usize,
214    /// }
215    ///
216    /// impl Iterator for Bits {
217    ///     type Item = bool;
218    ///
219    ///     fn next(&mut self) -> Option<bool> {
220    ///         Some(if self.b {
221    ///             self.b = false;
222    ///             self.j = self.k;
223    ///             true
224    ///         } else {
225    ///             self.j -= 1;
226    ///             if self.j == 0 {
227    ///                 self.k += 1;
228    ///                 self.b = true;
229    ///             }
230    ///             false
231    ///         })
232    ///     }
233    /// }
234    ///
235    /// impl Bits {
236    ///     fn new() -> Bits {
237    ///         Bits {
238    ///             b: true,
239    ///             k: 1,
240    ///             j: 1,
241    ///         }
242    ///     }
243    /// }
244    ///
245    /// let (c, o) = Float::non_dyadic_from_bits_prec(Bits::new(), 1);
246    /// assert_eq!(c.to_string(), "0.5");
247    /// assert_eq!(o, Less);
248    ///
249    /// let (c, o) = Float::non_dyadic_from_bits_prec(Bits::new(), 10);
250    /// assert_eq!(c.to_string(), "0.642");
251    /// assert_eq!(o, Less);
252    ///
253    /// let (c, o) = Float::non_dyadic_from_bits_prec(Bits::new(), 100);
254    /// assert_eq!(c.to_string(), "0.6416325606551538662938427702254");
255    /// assert_eq!(o, Less);
256    /// ```
257    #[inline]
258    pub fn non_dyadic_from_bits_prec<I: Iterator<Item = bool>>(
259        bits: I,
260        prec: u64,
261    ) -> (Self, Ordering) {
262        Self::non_dyadic_from_bits_prec_round(bits, prec, Nearest)
263    }
264}