malachite_float/float/arithmetic/power_of_10.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Float;
10use crate::{emulate_float_to_float_fn, emulate_rational_to_float_fn};
11use core::cmp::Ordering;
12use malachite_base::num::arithmetic::traits::{PowerOf10, PowerOf10Assign};
13use malachite_base::num::basic::floats::PrimitiveFloat;
14use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
15use malachite_base::num::logic::traits::SignificantBits;
16use malachite_base::rounding_modes::RoundingMode::{self, *};
17use malachite_q::Rational;
18
19impl Float {
20 #[allow(clippy::needless_pass_by_value)]
21 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result to the specified precision
22 /// and with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is
23 /// also returned, indicating whether the rounded power is less than, equal to, or greater than
24 /// the exact power. Although `NaN`s are not comparable to any [`Float`], whenever this function
25 /// returns a `NaN` it also returns `Equal`.
26 ///
27 /// See [`RoundingMode`] for a description of the possible rounding modes.
28 ///
29 /// $$
30 /// f(x,p,m) = 10^x+\varepsilon.
31 /// $$
32 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
33 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
34 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$.
35 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
36 /// 2^{\lfloor\log_2 10^x\rfloor-p}$.
37 ///
38 /// If the output has a precision, it is `prec`.
39 ///
40 /// Special cases:
41 /// - $f(\text{NaN},p,m)=\text{NaN}$
42 /// - $f(\infty,p,m)=\infty$
43 /// - $f(-\infty,p,m)=0.0$
44 /// - $f(\pm0.0,p,m)=1.0$
45 ///
46 /// Overflow and underflow:
47 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
48 /// returned instead.
49 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
50 /// returned instead.
51 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
52 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
53 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
54 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
55 /// instead.
56 ///
57 /// If you know you'll be using `Nearest`, consider using [`Float::power_of_10_of_float_prec`]
58 /// instead. If you know that your target precision is the precision of the input, consider
59 /// using [`Float::power_of_10_of_float_round`] instead. If both of these things are true,
60 /// consider using the [`PowerOf10`] implementation instead.
61 ///
62 /// # Worst-case complexity
63 /// $T(n) = O(n^{3/2} \log n \log\log n)$
64 ///
65 /// $M(n) = O(n \log n)$
66 ///
67 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
68 ///
69 /// # Panics
70 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
71 /// with the given precision.
72 ///
73 /// # Examples
74 /// ```
75 /// use malachite_base::rounding_modes::RoundingMode::*;
76 /// use malachite_float::Float;
77 /// use std::cmp::Ordering::*;
78 ///
79 /// let (p, o) = Float::power_of_10_of_float_prec_round(Float::from(0.5), 20, Floor);
80 /// assert_eq!(p.to_string(), "3.1622772");
81 /// assert_eq!(o, Less);
82 ///
83 /// let (p, o) = Float::power_of_10_of_float_prec_round(Float::from(0.5), 20, Ceiling);
84 /// assert_eq!(p.to_string(), "3.1622810");
85 /// assert_eq!(o, Greater);
86 /// ```
87 #[inline]
88 pub fn power_of_10_of_float_prec_round(
89 pow: Self,
90 prec: u64,
91 rm: RoundingMode,
92 ) -> (Self, Ordering) {
93 Self::unsigned_pow_prec_round(10, pow, prec, rm)
94 }
95
96 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result to the specified precision
97 /// and with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`]
98 /// is also returned, indicating whether the rounded power is less than, equal to, or greater
99 /// than the exact power. Although `NaN`s are not comparable to any [`Float`], whenever this
100 /// function returns a `NaN` it also returns `Equal`.
101 ///
102 /// See [`RoundingMode`] for a description of the possible rounding modes.
103 ///
104 /// $$
105 /// f(x,p,m) = 10^x+\varepsilon.
106 /// $$
107 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
108 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
109 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$.
110 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
111 /// 2^{\lfloor\log_2 10^x\rfloor-p}$.
112 ///
113 /// If the output has a precision, it is `prec`.
114 ///
115 /// Special cases:
116 /// - $f(\text{NaN},p,m)=\text{NaN}$
117 /// - $f(\infty,p,m)=\infty$
118 /// - $f(-\infty,p,m)=0.0$
119 /// - $f(\pm0.0,p,m)=1.0$
120 ///
121 /// Overflow and underflow:
122 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
123 /// returned instead.
124 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
125 /// returned instead.
126 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
127 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
128 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
129 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
130 /// instead.
131 ///
132 /// If you know you'll be using `Nearest`, consider using
133 /// [`Float::power_of_10_of_float_prec_ref`] instead. If you know that your target precision is
134 /// the precision of the input, consider using [`Float::power_of_10_of_float_round_ref`]
135 /// instead. If both of these things are true, consider using the [`PowerOf10`] implementation
136 /// instead.
137 ///
138 /// # Worst-case complexity
139 /// $T(n) = O(n^{3/2} \log n \log\log n)$
140 ///
141 /// $M(n) = O(n \log n)$
142 ///
143 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
144 ///
145 /// # Panics
146 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
147 /// with the given precision.
148 ///
149 /// # Examples
150 /// ```
151 /// use malachite_base::rounding_modes::RoundingMode::*;
152 /// use malachite_float::Float;
153 /// use std::cmp::Ordering::*;
154 ///
155 /// let (p, o) = Float::power_of_10_of_float_prec_round_ref(&Float::from(0.5), 20, Floor);
156 /// assert_eq!(p.to_string(), "3.1622772");
157 /// assert_eq!(o, Less);
158 ///
159 /// let (p, o) = Float::power_of_10_of_float_prec_round_ref(&Float::from(0.5), 20, Ceiling);
160 /// assert_eq!(p.to_string(), "3.1622810");
161 /// assert_eq!(o, Greater);
162 /// ```
163 #[inline]
164 pub fn power_of_10_of_float_prec_round_ref(
165 pow: &Self,
166 prec: u64,
167 rm: RoundingMode,
168 ) -> (Self, Ordering) {
169 Self::unsigned_pow_prec_round_ref(10, pow, prec, rm)
170 }
171
172 #[allow(clippy::needless_pass_by_value)]
173 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
174 /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
175 /// indicating whether the rounded power is less than, equal to, or greater than the exact
176 /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
177 /// `NaN` it also returns `Equal`.
178 ///
179 /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
180 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
181 /// the `Nearest` rounding mode.
182 ///
183 /// $$
184 /// f(x,p) = 10^x+\varepsilon.
185 /// $$
186 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
187 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$.
188 ///
189 /// If the output has a precision, it is `prec`.
190 ///
191 /// Special cases:
192 /// - $f(\text{NaN},p)=\text{NaN}$
193 /// - $f(\infty,p)=\infty$
194 /// - $f(-\infty,p)=0.0$
195 /// - $f(\pm0.0,p)=1.0$
196 ///
197 /// Overflow and underflow:
198 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
199 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
200 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
201 ///
202 /// If you want to use a rounding mode other than `Nearest`, consider using
203 /// [`Float::power_of_10_of_float_prec_round`] instead. If you know that your target precision
204 /// is the precision of the input, consider using the [`PowerOf10`] implementation instead.
205 ///
206 /// # Worst-case complexity
207 /// $T(n) = O(n^{3/2} \log n \log\log n)$
208 ///
209 /// $M(n) = O(n \log n)$
210 ///
211 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
212 ///
213 /// # Panics
214 /// Panics if `prec` is zero.
215 ///
216 /// # Examples
217 /// ```
218 /// use malachite_float::Float;
219 /// use std::cmp::Ordering::*;
220 ///
221 /// let (p, o) = Float::power_of_10_of_float_prec(Float::from(0.5), 20);
222 /// assert_eq!(p.to_string(), "3.1622772");
223 /// assert_eq!(o, Less);
224 ///
225 /// let (p, o) = Float::power_of_10_of_float_prec(Float::from(0.5), 53);
226 /// assert_eq!(p.to_string(), "3.1622776601683795");
227 /// assert_eq!(o, Greater);
228 /// ```
229 #[inline]
230 pub fn power_of_10_of_float_prec(pow: Self, prec: u64) -> (Self, Ordering) {
231 Self::power_of_10_of_float_prec_round(pow, prec, Nearest)
232 }
233
234 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
235 /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
236 /// indicating whether the rounded power is less than, equal to, or greater than the exact
237 /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
238 /// `NaN` it also returns `Equal`.
239 ///
240 /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
241 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
242 /// the `Nearest` rounding mode.
243 ///
244 /// $$
245 /// f(x,p) = 10^x+\varepsilon.
246 /// $$
247 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
248 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$.
249 ///
250 /// If the output has a precision, it is `prec`.
251 ///
252 /// Special cases:
253 /// - $f(\text{NaN},p)=\text{NaN}$
254 /// - $f(\infty,p)=\infty$
255 /// - $f(-\infty,p)=0.0$
256 /// - $f(\pm0.0,p)=1.0$
257 ///
258 /// Overflow and underflow:
259 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
260 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
261 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
262 ///
263 /// If you want to use a rounding mode other than `Nearest`, consider using
264 /// [`Float::power_of_10_of_float_prec_round_ref`] instead. If you know that your target
265 /// precision is the precision of the input, consider using the [`PowerOf10`] implementation
266 /// instead.
267 ///
268 /// # Worst-case complexity
269 /// $T(n) = O(n^{3/2} \log n \log\log n)$
270 ///
271 /// $M(n) = O(n \log n)$
272 ///
273 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
274 ///
275 /// # Panics
276 /// Panics if `prec` is zero.
277 ///
278 /// # Examples
279 /// ```
280 /// use malachite_float::Float;
281 /// use std::cmp::Ordering::*;
282 ///
283 /// let (p, o) = Float::power_of_10_of_float_prec_ref(&Float::from(0.5), 20);
284 /// assert_eq!(p.to_string(), "3.1622772");
285 /// assert_eq!(o, Less);
286 ///
287 /// let (p, o) = Float::power_of_10_of_float_prec_ref(&Float::from(0.5), 53);
288 /// assert_eq!(p.to_string(), "3.1622776601683795");
289 /// assert_eq!(o, Greater);
290 /// ```
291 #[inline]
292 pub fn power_of_10_of_float_prec_ref(pow: &Self, prec: u64) -> (Self, Ordering) {
293 Self::power_of_10_of_float_prec_round_ref(pow, prec, Nearest)
294 }
295
296 #[allow(clippy::needless_pass_by_value)]
297 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
298 /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
299 /// the rounded power is less than, equal to, or greater than the exact power. Although `NaN`s
300 /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
301 /// `Equal`.
302 ///
303 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
304 /// description of the possible rounding modes.
305 ///
306 /// $$
307 /// f(x,m) = 10^x+\varepsilon.
308 /// $$
309 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
310 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
311 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$, where $p$ is the precision of the input.
312 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
313 /// 2^{\lfloor\log_2 10^x\rfloor-p}$, where $p$ is the precision of the input.
314 ///
315 /// If the output has a precision, it is the precision of the input.
316 ///
317 /// Special cases:
318 /// - $f(\text{NaN},m)=\text{NaN}$
319 /// - $f(\infty,m)=\infty$
320 /// - $f(-\infty,m)=0.0$
321 /// - $f(\pm0.0,m)=1.0$
322 ///
323 /// See the [`Float::power_of_10_of_float_prec_round`] documentation for information on overflow
324 /// and underflow.
325 ///
326 /// If you want to specify an output precision, consider using
327 /// [`Float::power_of_10_of_float_prec_round`] instead. If you know you'll be using the
328 /// `Nearest` rounding mode, consider using the [`PowerOf10`] implementation instead.
329 ///
330 /// # Worst-case complexity
331 /// $T(n) = O(n^{3/2} \log n \log\log n)$
332 ///
333 /// $M(n) = O(n \log n)$
334 ///
335 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
336 ///
337 /// # Panics
338 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
339 /// precision.
340 ///
341 /// # Examples
342 /// ```
343 /// use malachite_base::rounding_modes::RoundingMode::*;
344 /// use malachite_float::Float;
345 /// use malachite_q::Rational;
346 /// use std::cmp::Ordering::*;
347 ///
348 /// let x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
349 ///
350 /// let (p, o) = Float::power_of_10_of_float_round(x.clone(), Floor);
351 /// assert_eq!(p.to_string(), "3.1622772");
352 /// assert_eq!(o, Less);
353 ///
354 /// let (p, o) = Float::power_of_10_of_float_round(x, Ceiling);
355 /// assert_eq!(p.to_string(), "3.1622810");
356 /// assert_eq!(o, Greater);
357 /// ```
358 #[inline]
359 pub fn power_of_10_of_float_round(pow: Self, rm: RoundingMode) -> (Self, Ordering) {
360 let prec = pow.significant_bits();
361 Self::power_of_10_of_float_prec_round_ref(&pow, prec, rm)
362 }
363
364 /// Computes $10^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
365 /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
366 /// whether the rounded power is less than, equal to, or greater than the exact power. Although
367 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
368 /// returns `Equal`.
369 ///
370 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
371 /// description of the possible rounding modes.
372 ///
373 /// $$
374 /// f(x,m) = 10^x+\varepsilon.
375 /// $$
376 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
377 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
378 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$, where $p$ is the precision of the input.
379 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
380 /// 2^{\lfloor\log_2 10^x\rfloor-p}$, where $p$ is the precision of the input.
381 ///
382 /// If the output has a precision, it is the precision of the input.
383 ///
384 /// Special cases:
385 /// - $f(\text{NaN},m)=\text{NaN}$
386 /// - $f(\infty,m)=\infty$
387 /// - $f(-\infty,m)=0.0$
388 /// - $f(\pm0.0,m)=1.0$
389 ///
390 /// See the [`Float::power_of_10_of_float_prec_round`] documentation for information on overflow
391 /// and underflow.
392 ///
393 /// If you want to specify an output precision, consider using
394 /// [`Float::power_of_10_of_float_prec_round_ref`] instead. If you know you'll be using the
395 /// `Nearest` rounding mode, consider using the [`PowerOf10`] implementation instead.
396 ///
397 /// # Worst-case complexity
398 /// $T(n) = O(n^{3/2} \log n \log\log n)$
399 ///
400 /// $M(n) = O(n \log n)$
401 ///
402 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
403 ///
404 /// # Panics
405 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
406 /// precision.
407 ///
408 /// # Examples
409 /// ```
410 /// use malachite_base::rounding_modes::RoundingMode::*;
411 /// use malachite_float::Float;
412 /// use malachite_q::Rational;
413 /// use std::cmp::Ordering::*;
414 ///
415 /// let x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
416 ///
417 /// let (p, o) = Float::power_of_10_of_float_round_ref(&x, Floor);
418 /// assert_eq!(p.to_string(), "3.1622772");
419 /// assert_eq!(o, Less);
420 ///
421 /// let (p, o) = Float::power_of_10_of_float_round_ref(&x, Ceiling);
422 /// assert_eq!(p.to_string(), "3.1622810");
423 /// assert_eq!(o, Greater);
424 /// ```
425 #[inline]
426 pub fn power_of_10_of_float_round_ref(pow: &Self, rm: RoundingMode) -> (Self, Ordering) {
427 Self::power_of_10_of_float_prec_round_ref(pow, pow.significant_bits(), rm)
428 }
429
430 /// Computes $10^x$, where $x$ is a [`Float`], in place, rounding the result to the specified
431 /// precision and with the specified rounding mode. An [`Ordering`] is returned, indicating
432 /// whether the rounded power is less than, equal to, or greater than the exact power. Although
433 /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
434 /// `NaN` it also returns `Equal`.
435 ///
436 /// See [`RoundingMode`] for a description of the possible rounding modes.
437 ///
438 /// $$
439 /// x \gets 10^x+\varepsilon.
440 /// $$
441 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
442 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
443 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$.
444 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
445 /// 2^{\lfloor\log_2 10^x\rfloor-p}$.
446 ///
447 /// If the output has a precision, it is `prec`.
448 ///
449 /// See the [`Float::power_of_10_of_float_prec_round`] documentation for information on special
450 /// cases, overflow, and underflow.
451 ///
452 /// If you know you'll be using `Nearest`, consider using
453 /// [`Float::power_of_10_of_float_prec_assign`] instead. If you know that your target precision
454 /// is the precision of the input, consider using [`Float::power_of_10_of_float_round_assign`]
455 /// instead. If both of these things are true, consider using the [`PowerOf10Assign`]
456 /// implementation instead.
457 ///
458 /// # Worst-case complexity
459 /// $T(n) = O(n^{3/2} \log n \log\log n)$
460 ///
461 /// $M(n) = O(n \log n)$
462 ///
463 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
464 ///
465 /// # Panics
466 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
467 /// with the given precision.
468 ///
469 /// # Examples
470 /// ```
471 /// use malachite_base::rounding_modes::RoundingMode::*;
472 /// use malachite_float::Float;
473 /// use std::cmp::Ordering::*;
474 ///
475 /// let mut x = Float::from(0.5);
476 /// assert_eq!(x.power_of_10_of_float_prec_round_assign(20, Floor), Less);
477 /// assert_eq!(x.to_string(), "3.1622772");
478 /// ```
479 #[inline]
480 pub fn power_of_10_of_float_prec_round_assign(
481 &mut self,
482 prec: u64,
483 rm: RoundingMode,
484 ) -> Ordering {
485 let (result, o) = Self::power_of_10_of_float_prec_round_ref(self, prec, rm);
486 *self = result;
487 o
488 }
489
490 /// Computes $10^x$, where $x$ is a [`Float`], in place, rounding the result to the nearest
491 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
492 /// rounded power is less than, equal to, or greater than the exact power. Although `NaN`s are
493 /// not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
494 /// returns `Equal`.
495 ///
496 /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
497 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
498 /// the `Nearest` rounding mode.
499 ///
500 /// $$
501 /// x \gets 10^x+\varepsilon.
502 /// $$
503 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
504 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$.
505 ///
506 /// If the output has a precision, it is `prec`.
507 ///
508 /// See the [`Float::power_of_10_of_float_prec`] documentation for information on special cases,
509 /// overflow, and underflow.
510 ///
511 /// If you want to use a rounding mode other than `Nearest`, consider using
512 /// [`Float::power_of_10_of_float_prec_round_assign`] instead. If you know that your target
513 /// precision is the precision of the input, consider using the [`PowerOf10Assign`]
514 /// implementation instead.
515 ///
516 /// # Worst-case complexity
517 /// $T(n) = O(n^{3/2} \log n \log\log n)$
518 ///
519 /// $M(n) = O(n \log n)$
520 ///
521 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
522 ///
523 /// # Panics
524 /// Panics if `prec` is zero.
525 ///
526 /// # Examples
527 /// ```
528 /// use malachite_float::Float;
529 /// use std::cmp::Ordering::*;
530 ///
531 /// let mut x = Float::from(0.5);
532 /// assert_eq!(x.power_of_10_of_float_prec_assign(20), Less);
533 /// assert_eq!(x.to_string(), "3.1622772");
534 /// ```
535 #[inline]
536 pub fn power_of_10_of_float_prec_assign(&mut self, prec: u64) -> Ordering {
537 self.power_of_10_of_float_prec_round_assign(prec, Nearest)
538 }
539
540 /// Computes $10^x$, where $x$ is a [`Float`], in place, rounding the result with the specified
541 /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded power is less
542 /// than, equal to, or greater than the exact power. Although `NaN`s are not comparable to any
543 /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
544 ///
545 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
546 /// description of the possible rounding modes.
547 ///
548 /// $$
549 /// x \gets 10^x+\varepsilon.
550 /// $$
551 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
552 /// - If $10^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
553 /// 2^{\lfloor\log_2 10^x\rfloor-p+1}$, where $p$ is the precision of the input.
554 /// - If $10^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
555 /// 2^{\lfloor\log_2 10^x\rfloor-p}$, where $p$ is the precision of the input.
556 ///
557 /// If the output has a precision, it is the precision of the input.
558 ///
559 /// See the [`Float::power_of_10_of_float_round`] documentation for information on special
560 /// cases, overflow, and underflow.
561 ///
562 /// If you want to specify an output precision, consider using
563 /// [`Float::power_of_10_of_float_prec_round_assign`] instead. If you know you'll be using the
564 /// `Nearest` rounding mode, consider using the [`PowerOf10Assign`] implementation instead.
565 ///
566 /// # Worst-case complexity
567 /// $T(n) = O(n^{3/2} \log n \log\log n)$
568 ///
569 /// $M(n) = O(n \log n)$
570 ///
571 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
572 ///
573 /// # Panics
574 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
575 /// precision.
576 ///
577 /// # Examples
578 /// ```
579 /// use malachite_base::rounding_modes::RoundingMode::*;
580 /// use malachite_float::Float;
581 /// use malachite_q::Rational;
582 /// use std::cmp::Ordering::*;
583 ///
584 /// let x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
585 ///
586 /// let mut x = x;
587 /// assert_eq!(x.power_of_10_of_float_round_assign(Ceiling), Greater);
588 /// assert_eq!(x.to_string(), "3.1622810");
589 /// ```
590 #[inline]
591 pub fn power_of_10_of_float_round_assign(&mut self, rm: RoundingMode) -> Ordering {
592 self.power_of_10_of_float_prec_round_assign(self.significant_bits(), rm)
593 }
594
595 #[allow(clippy::needless_pass_by_value)]
596 /// Computes $10^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
597 /// and with the specified rounding mode and returning the result as a [`Float`]. The
598 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
599 /// rounded power is less than, equal to, or greater than the exact power.
600 ///
601 /// See [`RoundingMode`] for a description of the possible rounding modes.
602 ///
603 /// $$
604 /// f(x,p,m) = 10^x+\varepsilon.
605 /// $$
606 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p+1}$.
607 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 10^x\rfloor-p}$.
608 ///
609 /// These bounds do not apply when the result overflows or underflows; see below.
610 ///
611 /// The output has precision `prec`.
612 ///
613 /// Special cases:
614 /// - $f(0,p,m)=1$.
615 ///
616 /// Overflow and underflow:
617 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
618 /// returned instead.
619 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
620 /// returned instead.
621 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
622 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
623 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
624 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
625 /// instead.
626 ///
627 /// If you know you'll be using `Nearest`, consider using [`Float::power_of_10_rational_prec`]
628 /// instead.
629 ///
630 /// # Worst-case complexity
631 /// $T(n) = O(n^{3/2} \log n \log\log n)$
632 ///
633 /// $M(n) = O(n \log n)$
634 ///
635 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
636 ///
637 /// # Panics
638 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
639 /// with the given precision (which is the case unless $x$ is a nonnegative integer).
640 ///
641 /// # Examples
642 /// ```
643 /// use malachite_base::rounding_modes::RoundingMode::*;
644 /// use malachite_float::Float;
645 /// use malachite_q::Rational;
646 /// use std::cmp::Ordering::*;
647 ///
648 /// let (p, o) =
649 /// Float::power_of_10_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
650 /// assert_eq!(p.to_string(), "3.88");
651 /// assert_eq!(o, Less);
652 ///
653 /// let (p, o) =
654 /// Float::power_of_10_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
655 /// assert_eq!(p.to_string(), "4.00");
656 /// assert_eq!(o, Greater);
657 ///
658 /// let (p, o) =
659 /// Float::power_of_10_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
660 /// assert_eq!(p.to_string(), "3.9810715");
661 /// assert_eq!(o, Less);
662 ///
663 /// let (p, o) =
664 /// Float::power_of_10_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
665 /// assert_eq!(p.to_string(), "3.9810753");
666 /// assert_eq!(o, Greater);
667 /// ```
668 #[inline]
669 pub fn power_of_10_rational_prec_round(
670 x: Rational,
671 prec: u64,
672 rm: RoundingMode,
673 ) -> (Self, Ordering) {
674 Self::unsigned_pow_rational_prec_round(10, x, prec, rm)
675 }
676
677 /// Computes $10^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
678 /// and with the specified rounding mode and returning the result as a [`Float`]. The
679 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
680 /// rounded power is less than, equal to, or greater than the exact power.
681 ///
682 /// See [`RoundingMode`] for a description of the possible rounding modes.
683 ///
684 /// $$
685 /// f(x,p,m) = 10^x+\varepsilon.
686 /// $$
687 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p+1}$.
688 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 10^x\rfloor-p}$.
689 ///
690 /// These bounds do not apply when the result overflows or underflows; see below.
691 ///
692 /// The output has precision `prec`.
693 ///
694 /// Special cases:
695 /// - $f(0,p,m)=1$.
696 ///
697 /// Overflow and underflow:
698 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
699 /// returned instead.
700 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
701 /// returned instead.
702 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
703 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
704 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
705 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
706 /// instead.
707 ///
708 /// If you know you'll be using `Nearest`, consider using
709 /// [`Float::power_of_10_rational_prec_ref`] instead.
710 ///
711 /// # Worst-case complexity
712 /// $T(n) = O(n^{3/2} \log n \log\log n)$
713 ///
714 /// $M(n) = O(n \log n)$
715 ///
716 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
717 ///
718 /// # Panics
719 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
720 /// with the given precision (which is the case unless $x$ is a nonnegative integer).
721 ///
722 /// # Examples
723 /// ```
724 /// use malachite_base::rounding_modes::RoundingMode::*;
725 /// use malachite_float::Float;
726 /// use malachite_q::Rational;
727 /// use std::cmp::Ordering::*;
728 ///
729 /// let (p, o) =
730 /// Float::power_of_10_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
731 /// assert_eq!(p.to_string(), "3.88");
732 /// assert_eq!(o, Less);
733 ///
734 /// let (p, o) = Float::power_of_10_rational_prec_round_ref(
735 /// &Rational::from_unsigneds(3u8, 5),
736 /// 5,
737 /// Ceiling,
738 /// );
739 /// assert_eq!(p.to_string(), "4.00");
740 /// assert_eq!(o, Greater);
741 ///
742 /// let (p, o) = Float::power_of_10_rational_prec_round_ref(
743 /// &Rational::from_unsigneds(3u8, 5),
744 /// 20,
745 /// Floor,
746 /// );
747 /// assert_eq!(p.to_string(), "3.9810715");
748 /// assert_eq!(o, Less);
749 ///
750 /// let (p, o) = Float::power_of_10_rational_prec_round_ref(
751 /// &Rational::from_unsigneds(3u8, 5),
752 /// 20,
753 /// Ceiling,
754 /// );
755 /// assert_eq!(p.to_string(), "3.9810753");
756 /// assert_eq!(o, Greater);
757 /// ```
758 #[inline]
759 pub fn power_of_10_rational_prec_round_ref(
760 x: &Rational,
761 prec: u64,
762 rm: RoundingMode,
763 ) -> (Self, Ordering) {
764 Self::unsigned_pow_rational_prec_round_ref(10, x, prec, rm)
765 }
766
767 #[allow(clippy::needless_pass_by_value)]
768 /// Computes $10^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of
769 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
770 /// by value. An [`Ordering`] is also returned, indicating whether the rounded power is less
771 /// than, equal to, or greater than the exact power.
772 ///
773 /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
774 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
775 /// the `Nearest` rounding mode.
776 ///
777 /// $$
778 /// f(x,p) = 10^x+\varepsilon,
779 /// $$
780 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 10^x\rfloor-p}$ (unless the result overflows or
781 /// underflows; see below).
782 ///
783 /// The output has precision `prec`.
784 ///
785 /// Special cases:
786 /// - $f(0,p)=1$.
787 ///
788 /// Overflow and underflow:
789 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
790 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
791 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
792 ///
793 /// If you want to use a rounding mode other than `Nearest`, consider using
794 /// [`Float::power_of_10_rational_prec_round`] instead.
795 ///
796 /// # Worst-case complexity
797 /// $T(n) = O(n^{3/2} \log n \log\log n)$
798 ///
799 /// $M(n) = O(n \log n)$
800 ///
801 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
802 ///
803 /// # Panics
804 /// Panics if `prec` is zero.
805 ///
806 /// # Examples
807 /// ```
808 /// use malachite_float::Float;
809 /// use malachite_q::Rational;
810 /// use std::cmp::Ordering::*;
811 ///
812 /// let (p, o) = Float::power_of_10_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
813 /// assert_eq!(p.to_string(), "4.00");
814 /// assert_eq!(o, Greater);
815 ///
816 /// let (p, o) = Float::power_of_10_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
817 /// assert_eq!(p.to_string(), "3.9810715");
818 /// assert_eq!(o, Less);
819 ///
820 /// let (p, o) = Float::power_of_10_rational_prec(Rational::from(0), 10);
821 /// assert_eq!(p.to_string(), "1.0000");
822 /// assert_eq!(o, Equal);
823 /// ```
824 #[inline]
825 pub fn power_of_10_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
826 Self::power_of_10_rational_prec_round(x, prec, Nearest)
827 }
828
829 /// Computes $10^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of
830 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
831 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded power is less
832 /// than, equal to, or greater than the exact power.
833 ///
834 /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
835 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
836 /// the `Nearest` rounding mode.
837 ///
838 /// $$
839 /// f(x,p) = 10^x+\varepsilon,
840 /// $$
841 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 10^x\rfloor-p}$ (unless the result overflows or
842 /// underflows; see below).
843 ///
844 /// The output has precision `prec`.
845 ///
846 /// Special cases:
847 /// - $f(0,p)=1$.
848 ///
849 /// Overflow and underflow:
850 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
851 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
852 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
853 ///
854 /// If you want to use a rounding mode other than `Nearest`, consider using
855 /// [`Float::power_of_10_rational_prec_round_ref`] instead.
856 ///
857 /// # Worst-case complexity
858 /// $T(n) = O(n^{3/2} \log n \log\log n)$
859 ///
860 /// $M(n) = O(n \log n)$
861 ///
862 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
863 ///
864 /// # Panics
865 /// Panics if `prec` is zero.
866 ///
867 /// # Examples
868 /// ```
869 /// use malachite_float::Float;
870 /// use malachite_q::Rational;
871 /// use std::cmp::Ordering::*;
872 ///
873 /// let (p, o) = Float::power_of_10_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
874 /// assert_eq!(p.to_string(), "4.00");
875 /// assert_eq!(o, Greater);
876 ///
877 /// let (p, o) = Float::power_of_10_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
878 /// assert_eq!(p.to_string(), "3.9810715");
879 /// assert_eq!(o, Less);
880 ///
881 /// let (p, o) = Float::power_of_10_rational_prec_ref(&Rational::from(0), 10);
882 /// assert_eq!(p.to_string(), "1.0000");
883 /// assert_eq!(o, Equal);
884 /// ```
885 #[inline]
886 pub fn power_of_10_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
887 Self::power_of_10_rational_prec_round_ref(x, prec, Nearest)
888 }
889}
890
891impl PowerOf10<Self> for Float {
892 /// Computes $10^x$, where $x$ is a [`Float`], taking it by value.
893 ///
894 /// If the output has a precision, it is the precision of the input. If the power is equidistant
895 /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
896 /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
897 ///
898 /// $$
899 /// f(x) = 10^x+\varepsilon.
900 /// $$
901 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
902 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$,
903 /// where $p$ is the precision of the input.
904 ///
905 /// Special cases:
906 /// - $f(\text{NaN})=\text{NaN}$
907 /// - $f(\infty)=\infty$
908 /// - $f(-\infty)=0.0$
909 /// - $f(\pm0.0)=1.0$
910 ///
911 /// See the [`Float::power_of_10_of_float_round`] documentation for information on overflow and
912 /// underflow.
913 ///
914 /// If you want to use a rounding mode other than `Nearest`, consider using
915 /// [`Float::power_of_10_of_float_round`] instead. If you want to specify the output precision,
916 /// consider using [`Float::power_of_10_of_float_prec`]. If you want both of these things,
917 /// consider using [`Float::power_of_10_of_float_prec_round`].
918 ///
919 /// # Worst-case complexity
920 /// $T(n) = O(n^{3/2} \log n \log\log n)$
921 ///
922 /// $M(n) = O(n \log n)$
923 ///
924 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
925 ///
926 /// # Examples
927 /// ```
928 /// use malachite_base::num::arithmetic::traits::PowerOf10;
929 /// use malachite_float::Float;
930 /// use malachite_q::Rational;
931 ///
932 /// let x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
933 ///
934 /// assert_eq!(Float::power_of_10(x).to_string(), "3.1622772");
935 /// ```
936 #[inline]
937 fn power_of_10(pow: Self) -> Self {
938 Self::power_of_10_of_float_round(pow, Nearest).0
939 }
940}
941
942impl PowerOf10<&Self> for Float {
943 /// Computes $10^x$, where $x$ is a [`Float`], taking it by reference.
944 ///
945 /// If the output has a precision, it is the precision of the input. If the power is equidistant
946 /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
947 /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
948 ///
949 /// $$
950 /// f(x) = 10^x+\varepsilon.
951 /// $$
952 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
953 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$,
954 /// where $p$ is the precision of the input.
955 ///
956 /// Special cases:
957 /// - $f(\text{NaN})=\text{NaN}$
958 /// - $f(\infty)=\infty$
959 /// - $f(-\infty)=0.0$
960 /// - $f(\pm0.0)=1.0$
961 ///
962 /// See the [`Float::power_of_10_of_float_round`] documentation for information on overflow and
963 /// underflow.
964 ///
965 /// If you want to use a rounding mode other than `Nearest`, consider using
966 /// [`Float::power_of_10_of_float_round_ref`] instead. If you want to specify the output
967 /// precision, consider using [`Float::power_of_10_of_float_prec_ref`]. If you want both of
968 /// these things, consider using [`Float::power_of_10_of_float_prec_round_ref`].
969 ///
970 /// # Worst-case complexity
971 /// $T(n) = O(n^{3/2} \log n \log\log n)$
972 ///
973 /// $M(n) = O(n \log n)$
974 ///
975 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
976 ///
977 /// # Examples
978 /// ```
979 /// use malachite_base::num::arithmetic::traits::PowerOf10;
980 /// use malachite_float::Float;
981 /// use malachite_q::Rational;
982 ///
983 /// let x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
984 ///
985 /// assert_eq!(Float::power_of_10(&x).to_string(), "3.1622772");
986 /// ```
987 #[inline]
988 fn power_of_10(pow: &Self) -> Self {
989 Self::power_of_10_of_float_round_ref(pow, Nearest).0
990 }
991}
992
993impl PowerOf10Assign for Float {
994 /// Computes $10^x$, where $x$ is a [`Float`], in place.
995 ///
996 /// If the output has a precision, it is the precision of the input. If the power is equidistant
997 /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
998 /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
999 ///
1000 /// $$
1001 /// x \gets 10^x+\varepsilon.
1002 /// $$
1003 /// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1004 /// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$,
1005 /// where $p$ is the precision of the input.
1006 ///
1007 /// See the [`Float::power_of_10_of_float_round`] documentation for information on special
1008 /// cases, overflow, and underflow.
1009 ///
1010 /// If you want to use a rounding mode other than `Nearest`, consider using
1011 /// [`Float::power_of_10_of_float_round_assign`] instead. If you want to specify the output
1012 /// precision, consider using [`Float::power_of_10_of_float_prec_assign`]. If you want both of
1013 /// these things, consider using [`Float::power_of_10_of_float_prec_round_assign`].
1014 ///
1015 /// # Worst-case complexity
1016 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1017 ///
1018 /// $M(n) = O(n \log n)$
1019 ///
1020 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1021 ///
1022 /// # Examples
1023 /// ```
1024 /// use malachite_base::num::arithmetic::traits::PowerOf10Assign;
1025 /// use malachite_float::Float;
1026 /// use malachite_q::Rational;
1027 ///
1028 /// let mut x = Float::from_rational_prec(Rational::from_signeds(1, 2), 20).0;
1029 /// x.power_of_10_assign();
1030 /// assert_eq!(x.to_string(), "3.1622772");
1031 /// ```
1032 #[inline]
1033 fn power_of_10_assign(&mut self) {
1034 self.power_of_10_of_float_round_assign(Nearest);
1035 }
1036}
1037
1038// This is equivalent to `mpfr_exp10` from `exp10.c`, MPFR 4.3.0, which likewise delegates to
1039// `mpfr_ui_pow`.
1040
1041/// Computes $10^x$, where $x$ is a primitive float, returning the result as a primitive float of
1042/// the same type. Using this function is more accurate than using `x.exp2()` or the `exp2` function
1043/// provided by `libm`.
1044///
1045/// $$
1046/// f(x) = 10^x+\varepsilon.
1047/// $$
1048/// - If $10^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1049/// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$, where
1050/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1051/// [`f64`], but less if the output is subnormal).
1052///
1053/// Special cases:
1054/// - $f(\text{NaN})=\text{NaN}$
1055/// - $f(\infty)=\infty$
1056/// - $f(-\infty)=0.0$
1057/// - $f(\pm0.0)=1.0$
1058///
1059/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1060/// `x` gives `0.0`.
1061///
1062/// # Worst-case complexity
1063/// Constant time and additional memory.
1064///
1065/// # Examples
1066/// ```
1067/// use malachite_base::num::float::NiceFloat;
1068/// use malachite_float::float::arithmetic::power_of_10::primitive_float_power_of_10;
1069///
1070/// assert_eq!(
1071/// NiceFloat(primitive_float_power_of_10(0.5f64)),
1072/// NiceFloat(3.1622776601683795)
1073/// );
1074/// assert_eq!(
1075/// NiceFloat(primitive_float_power_of_10(-3.0f64)),
1076/// NiceFloat(0.001)
1077/// );
1078/// ```
1079#[inline]
1080#[allow(clippy::type_repetition_in_bounds)]
1081pub fn primitive_float_power_of_10<T: PrimitiveFloat>(x: T) -> T
1082where
1083 Float: From<T> + PartialOrd<T>,
1084 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1085{
1086 emulate_float_to_float_fn(|x2, prec| Float::unsigned_pow_prec(10, x2, prec), x)
1087}
1088
1089/// Computes $10^x$, where $x$ is a [`Rational`], returning the result as a primitive float.
1090///
1091/// $$
1092/// f(x) = 10^x+\varepsilon.
1093/// $$
1094/// - If $10^x$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
1095/// - If $10^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 10^x\rfloor-p}$, where
1096/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1097/// [`f64`], but less if the output is subnormal).
1098///
1099/// Special cases:
1100/// - $f(0)=1$
1101///
1102/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1103/// `x` gives `0.0`.
1104///
1105/// # Worst-case complexity
1106/// Constant time and additional memory.
1107///
1108/// # Examples
1109/// ```
1110/// use malachite_base::num::float::NiceFloat;
1111/// use malachite_float::float::arithmetic::power_of_10::primitive_float_power_of_10_rational;
1112/// use malachite_q::Rational;
1113///
1114/// assert_eq!(
1115/// NiceFloat(primitive_float_power_of_10_rational::<f32>(
1116/// &Rational::from_signeds(1, 3)
1117/// )),
1118/// NiceFloat(2.1544347)
1119/// );
1120/// ```
1121#[inline]
1122#[allow(clippy::type_repetition_in_bounds)]
1123pub fn primitive_float_power_of_10_rational<T: PrimitiveFloat>(x: &Rational) -> T
1124where
1125 Float: PartialOrd<T>,
1126 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1127{
1128 emulate_rational_to_float_fn(
1129 |q, prec| Float::unsigned_pow_rational_prec_ref(10, q, prec),
1130 x,
1131 )
1132}