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}