Skip to main content

malachite_float/float/arithmetic/
cbrt.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::float::arithmetic::root::{primitive_float_root_u, primitive_float_root_u_rational};
11use core::cmp::Ordering;
12use malachite_base::num::arithmetic::traits::{Cbrt, CbrtAssign};
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;
17use malachite_q::Rational;
18
19impl Float {
20    /// Takes the cube root of a [`Float`], rounding the result to the specified precision and with
21    /// the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also
22    /// returned, indicating whether the rounded cube root is less than, equal to, or greater than
23    /// the exact cube root. Although `NaN`s are not comparable to any [`Float`], whenever this
24    /// function returns a `NaN` it also returns `Equal`.
25    ///
26    /// Unlike the square root, the cube root of a negative number is a (negative) real number, so a
27    /// negative input does not produce a `NaN`.
28    ///
29    /// $$
30    /// f(x,p,m) = \sqrt\[3\]{x}+\varepsilon.
31    /// $$
32    /// - If $\sqrt\[3\]{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
33    ///   be 0.
34    /// - If $\sqrt\[3\]{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
35    ///   2^{\lfloor\log_2 |\sqrt\[3\]{x}|\rfloor-p+1}$.
36    /// - If $\sqrt\[3\]{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
37    ///   2^{\lfloor\log_2 |\sqrt\[3\]{x}|\rfloor-p}$.
38    ///
39    /// If the output has a precision, it is `prec`.
40    ///
41    /// Special cases:
42    /// - $f(\text{NaN},p,m)=\text{NaN}$
43    /// - $f(\infty,p,m)=\infty$
44    /// - $f(-\infty,p,m)=-\infty$
45    /// - $f(0.0,p,m)=0.0$
46    /// - $f(-0.0,p,m)=-0.0$
47    ///
48    /// The result never overflows or underflows: its exponent is close to the exponent of $x$
49    /// divided by 3.
50    ///
51    /// If you know you'll be using `Nearest`, consider using [`Float::cbrt_prec`] instead. If you
52    /// know that your target precision is the precision of the input, consider using
53    /// [`Float::cbrt_round`] instead. If both of these things are true, consider using the [`Cbrt`]
54    /// implementation instead.
55    ///
56    /// # Worst-case complexity
57    /// $T(n) = O(n^{3/2} \log n \log\log n)$
58    ///
59    /// $M(n) = O(n \log n)$
60    ///
61    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
62    /// self.significant_bits())`.
63    ///
64    /// # Panics
65    /// Panics if `prec` is zero, or if `rm` is `Exact` but the cube root is not exact.
66    ///
67    /// # Examples
68    /// ```
69    /// use malachite_base::rounding_modes::RoundingMode::*;
70    /// use malachite_float::Float;
71    /// use std::cmp::Ordering::*;
72    ///
73    /// let (cbrt, o) = Float::from(27.0).cbrt_prec_round(10, Floor);
74    /// assert_eq!(cbrt.to_string(), "3.0000");
75    /// assert_eq!(o, Equal);
76    ///
77    /// let (cbrt, o) = Float::from(2.0).cbrt_prec_round(10, Floor);
78    /// assert_eq!(cbrt.to_string(), "1.2598");
79    /// assert_eq!(o, Less);
80    ///
81    /// let (cbrt, o) = Float::from(2.0).cbrt_prec_round(10, Ceiling);
82    /// assert_eq!(cbrt.to_string(), "1.2617");
83    /// assert_eq!(o, Greater);
84    /// ```
85    #[inline]
86    pub fn cbrt_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
87        self.root_u_prec_round(3, prec, rm)
88    }
89
90    /// Takes the cube root of a [`Float`], rounding the result to the specified precision and with
91    /// the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also
92    /// returned, indicating whether the rounded cube root is less than, equal to, or greater than
93    /// the exact cube root. Although `NaN`s are not comparable to any [`Float`], whenever this
94    /// function returns a `NaN` it also returns `Equal`.
95    ///
96    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
97    /// and underflow.
98    ///
99    /// If you know you'll be using `Nearest`, consider using [`Float::cbrt_prec_ref`] instead. If
100    /// you know that your target precision is the precision of the input, consider using
101    /// [`Float::cbrt_round_ref`] instead. If both of these things are true, consider using the
102    /// [`Cbrt`] implementation instead.
103    ///
104    /// # Worst-case complexity
105    /// $T(n) = O(n^{3/2} \log n \log\log n)$
106    ///
107    /// $M(n) = O(n \log n)$
108    ///
109    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
110    /// self.significant_bits())`.
111    ///
112    /// # Panics
113    /// Panics if `prec` is zero, or if `rm` is `Exact` but the cube root is not exact.
114    ///
115    /// # Examples
116    /// ```
117    /// use malachite_base::rounding_modes::RoundingMode::*;
118    /// use malachite_float::Float;
119    /// use std::cmp::Ordering::*;
120    ///
121    /// let (cbrt, o) = Float::from(2.0).cbrt_prec_round_ref(10, Floor);
122    /// assert_eq!(cbrt.to_string(), "1.2598");
123    /// assert_eq!(o, Less);
124    ///
125    /// let (cbrt, o) = Float::from(2.0).cbrt_prec_round_ref(10, Ceiling);
126    /// assert_eq!(cbrt.to_string(), "1.2617");
127    /// assert_eq!(o, Greater);
128    /// ```
129    #[inline]
130    pub fn cbrt_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
131        self.root_u_prec_round_ref(3, prec, rm)
132    }
133
134    /// Takes the cube root of a [`Float`], rounding the result to the specified precision and to
135    /// the nearest value. The [`Float`] is taken by value. An [`Ordering`] is also returned,
136    /// indicating whether the rounded cube root is less than, equal to, or greater than the exact
137    /// cube root. Although `NaN`s are not comparable to any [`Float`], whenever this function
138    /// returns a `NaN` it also returns `Equal`.
139    ///
140    /// If the cube root is equidistant from two [`Float`]s with the specified precision, the
141    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
142    /// description of the `Nearest` rounding mode.
143    ///
144    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
145    /// and underflow.
146    ///
147    /// If you want to use a rounding mode other than `Nearest`, consider using
148    /// [`Float::cbrt_prec_round`] instead.
149    ///
150    /// # Worst-case complexity
151    /// $T(n) = O(n^{3/2} \log n \log\log n)$
152    ///
153    /// $M(n) = O(n \log n)$
154    ///
155    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
156    /// self.significant_bits())`.
157    ///
158    /// # Panics
159    /// Panics if `prec` is zero.
160    ///
161    /// # Examples
162    /// ```
163    /// use malachite_float::Float;
164    /// use std::cmp::Ordering::*;
165    ///
166    /// let (cbrt, o) = Float::from(27.0).cbrt_prec(10);
167    /// assert_eq!(cbrt.to_string(), "3.0000");
168    /// assert_eq!(o, Equal);
169    ///
170    /// let (cbrt, o) = Float::from(2.0).cbrt_prec(10);
171    /// assert_eq!(cbrt.to_string(), "1.2598");
172    /// assert_eq!(o, Less);
173    /// ```
174    #[inline]
175    pub fn cbrt_prec(self, prec: u64) -> (Self, Ordering) {
176        self.root_u_prec(3, prec)
177    }
178
179    /// Takes the cube root of a [`Float`], rounding the result to the specified precision and to
180    /// the nearest value. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
181    /// indicating whether the rounded cube root is less than, equal to, or greater than the exact
182    /// cube root. Although `NaN`s are not comparable to any [`Float`], whenever this function
183    /// returns a `NaN` it also returns `Equal`.
184    ///
185    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
186    /// and underflow.
187    ///
188    /// If you want to use a rounding mode other than `Nearest`, consider using
189    /// [`Float::cbrt_prec_round_ref`] instead.
190    ///
191    /// # Worst-case complexity
192    /// $T(n) = O(n^{3/2} \log n \log\log n)$
193    ///
194    /// $M(n) = O(n \log n)$
195    ///
196    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
197    /// self.significant_bits())`.
198    ///
199    /// # Panics
200    /// Panics if `prec` is zero.
201    ///
202    /// # Examples
203    /// ```
204    /// use malachite_float::Float;
205    /// use std::cmp::Ordering::*;
206    ///
207    /// let (cbrt, o) = Float::from(2.0).cbrt_prec_ref(10);
208    /// assert_eq!(cbrt.to_string(), "1.2598");
209    /// assert_eq!(o, Less);
210    /// ```
211    #[inline]
212    pub fn cbrt_prec_ref(&self, prec: u64) -> (Self, Ordering) {
213        self.root_u_prec_ref(3, prec)
214    }
215
216    /// Takes the cube root of a [`Float`], rounding the result to the precision of the input and
217    /// with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also
218    /// returned, indicating whether the rounded cube root is less than, equal to, or greater than
219    /// the exact cube root. Although `NaN`s are not comparable to any [`Float`], whenever this
220    /// function returns a `NaN` it also returns `Equal`.
221    ///
222    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
223    /// and underflow.
224    ///
225    /// If you want to specify an output precision, consider using [`Float::cbrt_prec_round`]
226    /// instead.
227    ///
228    /// # Worst-case complexity
229    /// $T(n) = O(n^{3/2} \log n \log\log n)$
230    ///
231    /// $M(n) = O(n \log n)$
232    ///
233    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
234    ///
235    /// # Panics
236    /// Panics if `rm` is `Exact` but the cube root is not exact.
237    ///
238    /// # Examples
239    /// ```
240    /// use malachite_base::rounding_modes::RoundingMode::*;
241    /// use malachite_float::Float;
242    /// use std::cmp::Ordering::*;
243    ///
244    /// let (cbrt, o) = Float::from(-8.0).cbrt_round(Floor);
245    /// assert_eq!(cbrt.to_string(), "-2.0");
246    /// assert_eq!(o, Equal);
247    /// ```
248    #[inline]
249    pub fn cbrt_round(self, rm: RoundingMode) -> (Self, Ordering) {
250        self.root_u_round(3, rm)
251    }
252
253    /// Takes the cube root of a [`Float`], rounding the result to the precision of the input and
254    /// with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is
255    /// also returned, indicating whether the rounded cube root is less than, equal to, or greater
256    /// than the exact cube root. Although `NaN`s are not comparable to any [`Float`], whenever this
257    /// function returns a `NaN` it also returns `Equal`.
258    ///
259    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
260    /// and underflow.
261    ///
262    /// If you want to specify an output precision, consider using [`Float::cbrt_prec_round_ref`]
263    /// instead.
264    ///
265    /// # Worst-case complexity
266    /// $T(n) = O(n^{3/2} \log n \log\log n)$
267    ///
268    /// $M(n) = O(n \log n)$
269    ///
270    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
271    ///
272    /// # Panics
273    /// Panics if `rm` is `Exact` but the cube root is not exact.
274    ///
275    /// # Examples
276    /// ```
277    /// use malachite_base::rounding_modes::RoundingMode::*;
278    /// use malachite_float::Float;
279    /// use std::cmp::Ordering::*;
280    ///
281    /// let (cbrt, o) = (&Float::from(-8.0)).cbrt_round_ref(Floor);
282    /// assert_eq!(cbrt.to_string(), "-2.0");
283    /// assert_eq!(o, Equal);
284    /// ```
285    #[inline]
286    pub fn cbrt_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
287        self.root_u_round_ref(3, rm)
288    }
289
290    /// Takes the cube root of a [`Float`] in place, rounding the result to the specified precision
291    /// and with the specified rounding mode. An [`Ordering`] is returned, indicating whether the
292    /// rounded cube root is less than, equal to, or greater than the exact cube root. Although
293    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
294    /// `NaN` it also returns `Equal`.
295    ///
296    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
297    /// and underflow.
298    ///
299    /// # Worst-case complexity
300    /// $T(n) = O(n^{3/2} \log n \log\log n)$
301    ///
302    /// $M(n) = O(n \log n)$
303    ///
304    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
305    /// self.significant_bits())`.
306    ///
307    /// # Panics
308    /// Panics if `prec` is zero, or if `rm` is `Exact` but the cube root is not exact.
309    ///
310    /// # Examples
311    /// ```
312    /// use malachite_base::rounding_modes::RoundingMode::*;
313    /// use malachite_float::Float;
314    /// use std::cmp::Ordering::*;
315    ///
316    /// let mut x = Float::from(2.0);
317    /// assert_eq!(x.cbrt_prec_round_assign(10, Floor), Less);
318    /// assert_eq!(x.to_string(), "1.2598");
319    /// ```
320    #[inline]
321    pub fn cbrt_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
322        self.root_u_prec_round_assign(3, prec, rm)
323    }
324
325    /// Takes the cube root of a [`Float`] in place, rounding the result to the specified precision
326    /// and to the nearest value. An [`Ordering`] is returned, indicating whether the rounded cube
327    /// root is less than, equal to, or greater than the exact cube root. Although `NaN`s are not
328    /// comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
329    /// returns `Equal`.
330    ///
331    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
332    /// and underflow.
333    ///
334    /// # Worst-case complexity
335    /// $T(n) = O(n^{3/2} \log n \log\log n)$
336    ///
337    /// $M(n) = O(n \log n)$
338    ///
339    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec,
340    /// self.significant_bits())`.
341    ///
342    /// # Panics
343    /// Panics if `prec` is zero.
344    ///
345    /// # Examples
346    /// ```
347    /// use malachite_float::Float;
348    /// use std::cmp::Ordering::*;
349    ///
350    /// let mut x = Float::from(2.0);
351    /// assert_eq!(x.cbrt_prec_assign(10), Less);
352    /// assert_eq!(x.to_string(), "1.2598");
353    /// ```
354    #[inline]
355    pub fn cbrt_prec_assign(&mut self, prec: u64) -> Ordering {
356        self.root_u_prec_assign(3, prec)
357    }
358
359    /// Takes the cube root of a [`Float`] in place, rounding the result to the precision of the
360    /// input and with the specified rounding mode. An [`Ordering`] is returned, indicating whether
361    /// the rounded cube root is less than, equal to, or greater than the exact cube root. Although
362    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
363    /// `NaN` it also returns `Equal`.
364    ///
365    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
366    /// and underflow.
367    ///
368    /// # Worst-case complexity
369    /// $T(n) = O(n^{3/2} \log n \log\log n)$
370    ///
371    /// $M(n) = O(n \log n)$
372    ///
373    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
374    ///
375    /// # Panics
376    /// Panics if `rm` is `Exact` but the cube root is not exact.
377    ///
378    /// # Examples
379    /// ```
380    /// use malachite_base::rounding_modes::RoundingMode::*;
381    /// use malachite_float::Float;
382    /// use std::cmp::Ordering::*;
383    ///
384    /// let mut x = Float::from(-8.0);
385    /// assert_eq!(x.cbrt_round_assign(Floor), Equal);
386    /// assert_eq!(x.to_string(), "-2.0");
387    /// ```
388    #[inline]
389    pub fn cbrt_round_assign(&mut self, rm: RoundingMode) -> Ordering {
390        self.root_u_round_assign(3, rm)
391    }
392
393    /// Takes the cube root of a [`Rational`], producing a [`Float`], rounding the result to the
394    /// specified precision and with the specified rounding mode. The [`Rational`] is taken by
395    /// value. An [`Ordering`] is also returned, indicating whether the rounded cube root is less
396    /// than, equal to, or greater than the exact cube root.
397    ///
398    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
399    /// and underflow.
400    ///
401    /// # Worst-case complexity
402    /// $T(n) = O(n^{3/2} \log n \log\log n)$
403    ///
404    /// $M(n) = O(n \log n)$
405    ///
406    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, x.significant_bits())`.
407    ///
408    /// # Panics
409    /// Panics if `prec` is zero, or if `rm` is `Exact` but the cube root is not exact.
410    ///
411    /// # Examples
412    /// ```
413    /// use malachite_base::rounding_modes::RoundingMode::*;
414    /// use malachite_float::Float;
415    /// use malachite_q::Rational;
416    /// use std::cmp::Ordering::*;
417    ///
418    /// let (cbrt, o) = Float::cbrt_rational_prec_round(Rational::from(27), 10, Floor);
419    /// assert_eq!(cbrt.to_string(), "3.0000");
420    /// assert_eq!(o, Equal);
421    /// ```
422    #[inline]
423    pub fn cbrt_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
424        Self::root_u_rational_prec_round(x, 3, prec, rm)
425    }
426
427    /// Takes the cube root of a [`Rational`], producing a [`Float`], rounding the result to the
428    /// specified precision and with the specified rounding mode. The [`Rational`] is taken by
429    /// reference. An [`Ordering`] is also returned, indicating whether the rounded cube root is
430    /// less than, equal to, or greater than the exact cube root.
431    ///
432    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
433    /// and underflow.
434    ///
435    /// # Worst-case complexity
436    /// $T(n) = O(n^{3/2} \log n \log\log n)$
437    ///
438    /// $M(n) = O(n \log n)$
439    ///
440    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, x.significant_bits())`.
441    ///
442    /// # Panics
443    /// Panics if `prec` is zero, or if `rm` is `Exact` but the cube root is not exact.
444    ///
445    /// # Examples
446    /// ```
447    /// use malachite_base::rounding_modes::RoundingMode::*;
448    /// use malachite_float::Float;
449    /// use malachite_q::Rational;
450    /// use std::cmp::Ordering::*;
451    ///
452    /// let (cbrt, o) = Float::cbrt_rational_prec_round_ref(&Rational::from(27), 10, Floor);
453    /// assert_eq!(cbrt.to_string(), "3.0000");
454    /// assert_eq!(o, Equal);
455    /// ```
456    #[inline]
457    pub fn cbrt_rational_prec_round_ref(
458        x: &Rational,
459        prec: u64,
460        rm: RoundingMode,
461    ) -> (Self, Ordering) {
462        Self::root_u_rational_prec_round_ref(x, 3, prec, rm)
463    }
464
465    /// Takes the cube root of a [`Rational`], producing a [`Float`], rounding the result to the
466    /// specified precision and to the nearest value. The [`Rational`] is taken by value. An
467    /// [`Ordering`] is also returned, indicating whether the rounded cube root is less than, equal
468    /// to, or greater than the exact cube root.
469    ///
470    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
471    /// and underflow.
472    ///
473    /// # Worst-case complexity
474    /// $T(n) = O(n^{3/2} \log n \log\log n)$
475    ///
476    /// $M(n) = O(n \log n)$
477    ///
478    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, x.significant_bits())`.
479    ///
480    /// # Panics
481    /// Panics if `prec` is zero.
482    ///
483    /// # Examples
484    /// ```
485    /// use malachite_float::Float;
486    /// use malachite_q::Rational;
487    /// use std::cmp::Ordering::*;
488    ///
489    /// let (cbrt, o) = Float::cbrt_rational_prec(Rational::from(27), 10);
490    /// assert_eq!(cbrt.to_string(), "3.0000");
491    /// assert_eq!(o, Equal);
492    /// ```
493    #[inline]
494    pub fn cbrt_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
495        Self::root_u_rational_prec(x, 3, prec)
496    }
497
498    /// Takes the cube root of a [`Rational`], producing a [`Float`], rounding the result to the
499    /// specified precision and to the nearest value. The [`Rational`] is taken by reference. An
500    /// [`Ordering`] is also returned, indicating whether the rounded cube root is less than, equal
501    /// to, or greater than the exact cube root.
502    ///
503    /// See the [`Float::cbrt_prec_round`] documentation for information on special cases, overflow,
504    /// and underflow.
505    ///
506    /// # Worst-case complexity
507    /// $T(n) = O(n^{3/2} \log n \log\log n)$
508    ///
509    /// $M(n) = O(n \log n)$
510    ///
511    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, x.significant_bits())`.
512    ///
513    /// # Panics
514    /// Panics if `prec` is zero.
515    ///
516    /// # Examples
517    /// ```
518    /// use malachite_float::Float;
519    /// use malachite_q::Rational;
520    /// use std::cmp::Ordering::*;
521    ///
522    /// let (cbrt, o) = Float::cbrt_rational_prec_ref(&Rational::from(27), 10);
523    /// assert_eq!(cbrt.to_string(), "3.0000");
524    /// assert_eq!(o, Equal);
525    /// ```
526    #[inline]
527    pub fn cbrt_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
528        Self::root_u_rational_prec_ref(x, 3, prec)
529    }
530}
531
532impl Cbrt for Float {
533    type Output = Self;
534
535    /// Takes the cube root of a [`Float`], taking it by value.
536    ///
537    /// If the output has a precision, it is the precision of the input. If the cube root is
538    /// equidistant from two [`Float`]s with that precision, the [`Float`] with fewer 1s in its
539    /// binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
540    /// mode.
541    ///
542    /// Unlike the square root, the cube root of a negative number is a (negative) real number, so a
543    /// negative input does not produce a `NaN`.
544    ///
545    /// $$
546    /// f(x) = \sqrt\[3\]{x}+\varepsilon.
547    /// $$
548    /// - If $\sqrt\[3\]{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
549    ///   be 0.
550    /// - If $\sqrt\[3\]{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
551    ///   |\sqrt\[3\]{x}|\rfloor-p}$, where $p$ is the precision of the input.
552    ///
553    /// Special cases:
554    /// - $f(\text{NaN})=\text{NaN}$
555    /// - $f(\infty)=\infty$
556    /// - $f(-\infty)=-\infty$
557    /// - $f(0.0)=0.0$
558    /// - $f(-0.0)=-0.0$
559    ///
560    /// Neither overflow nor underflow is possible.
561    ///
562    /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::cbrt_prec`]
563    /// instead. If you want to specify the output precision, consider using [`Float::cbrt_round`].
564    /// If you want both of these things, consider using [`Float::cbrt_prec_round`].
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    /// # Examples
574    /// ```
575    /// use malachite_base::num::arithmetic::traits::Cbrt;
576    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
577    /// use malachite_float::Float;
578    ///
579    /// assert!(Float::NAN.cbrt().is_nan());
580    /// assert_eq!(Float::INFINITY.cbrt(), Float::INFINITY);
581    /// assert_eq!(Float::NEGATIVE_INFINITY.cbrt(), Float::NEGATIVE_INFINITY);
582    /// assert_eq!(Float::from(27.0).cbrt(), 3.0);
583    /// assert_eq!(Float::from(-8.0).cbrt(), -2.0);
584    /// ```
585    #[inline]
586    fn cbrt(self) -> Self {
587        let prec = self.significant_bits();
588        self.cbrt_prec(prec).0
589    }
590}
591
592impl Cbrt for &Float {
593    type Output = Float;
594
595    /// Takes the cube root of a [`Float`], taking it by reference.
596    ///
597    /// If the output has a precision, it is the precision of the input. If the cube root is
598    /// equidistant from two [`Float`]s with that precision, the [`Float`] with fewer 1s in its
599    /// binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
600    /// mode.
601    ///
602    /// Unlike the square root, the cube root of a negative number is a (negative) real number, so a
603    /// negative input does not produce a `NaN`.
604    ///
605    /// $$
606    /// f(x) = \sqrt\[3\]{x}+\varepsilon.
607    /// $$
608    /// - If $\sqrt\[3\]{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
609    ///   be 0.
610    /// - If $\sqrt\[3\]{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
611    ///   |\sqrt\[3\]{x}|\rfloor-p}$, where $p$ is the precision of the input.
612    ///
613    /// Special cases:
614    /// - $f(\text{NaN})=\text{NaN}$
615    /// - $f(\infty)=\infty$
616    /// - $f(-\infty)=-\infty$
617    /// - $f(0.0)=0.0$
618    /// - $f(-0.0)=-0.0$
619    ///
620    /// Neither overflow nor underflow is possible.
621    ///
622    /// If you want to use a rounding mode other than `Nearest`, consider using
623    /// [`Float::cbrt_prec_ref`] instead. If you want to specify the output precision, consider
624    /// using [`Float::cbrt_round_ref`]. If you want both of these things, consider using
625    /// [`Float::cbrt_prec_round_ref`].
626    ///
627    /// # Worst-case complexity
628    /// $T(n) = O(n^{3/2} \log n \log\log n)$
629    ///
630    /// $M(n) = O(n \log n)$
631    ///
632    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
633    ///
634    /// # Examples
635    /// ```
636    /// use malachite_base::num::arithmetic::traits::Cbrt;
637    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
638    /// use malachite_float::Float;
639    ///
640    /// assert!((&Float::NAN).cbrt().is_nan());
641    /// assert_eq!((&Float::INFINITY).cbrt(), Float::INFINITY);
642    /// assert_eq!((&Float::NEGATIVE_INFINITY).cbrt(), Float::NEGATIVE_INFINITY);
643    /// assert_eq!((&Float::from(27.0)).cbrt(), 3.0);
644    /// assert_eq!((&Float::from(-8.0)).cbrt(), -2.0);
645    /// ```
646    #[inline]
647    fn cbrt(self) -> Float {
648        let prec = self.significant_bits();
649        self.cbrt_prec_ref(prec).0
650    }
651}
652
653impl CbrtAssign for Float {
654    /// Takes the cube root of a [`Float`] in place.
655    ///
656    /// If the output has a precision, it is the precision of the input. If the cube root is
657    /// equidistant from two [`Float`]s with that precision, the [`Float`] with fewer 1s in its
658    /// binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
659    /// mode.
660    ///
661    /// Unlike the square root, the cube root of a negative number is a (negative) real number, so a
662    /// negative input does not produce a `NaN`.
663    ///
664    /// $$
665    /// x\gets = \sqrt\[3\]{x}+\varepsilon.
666    /// $$
667    /// - If $\sqrt\[3\]{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
668    ///   be 0.
669    /// - If $\sqrt\[3\]{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
670    ///   |\sqrt\[3\]{x}|\rfloor-p}$, where $p$ is the precision of the input.
671    ///
672    /// See the [`Float::cbrt`] documentation for information on special cases, overflow, and
673    /// underflow.
674    ///
675    /// # Worst-case complexity
676    /// $T(n) = O(n^{3/2} \log n \log\log n)$
677    ///
678    /// $M(n) = O(n \log n)$
679    ///
680    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
681    ///
682    /// # Examples
683    /// ```
684    /// use malachite_base::num::arithmetic::traits::CbrtAssign;
685    /// use malachite_float::Float;
686    ///
687    /// let mut x = Float::from(27.0);
688    /// x.cbrt_assign();
689    /// assert_eq!(x, 3.0);
690    ///
691    /// let mut x = Float::from(-8.0);
692    /// x.cbrt_assign();
693    /// assert_eq!(x, -2.0);
694    /// ```
695    #[inline]
696    fn cbrt_assign(&mut self) {
697        let prec = self.significant_bits();
698        self.cbrt_prec_assign(prec);
699    }
700}
701
702/// Takes the cube root of a primitive float, returning a correctly-rounded result.
703///
704/// Unlike the `cbrt` methods of `f32` and `f64` (which are not guaranteed to be correctly rounded),
705/// this function returns the primitive float closest to the real cube root of the input, with ties
706/// rounded to even. It is computed by taking the cube root of the exact value of the input at the
707/// appropriate precision.
708///
709/// $$
710/// f(x) = \sqrt\[3\]{x}.
711/// $$
712///
713/// # Worst-case complexity
714/// Constant time and additional memory.
715///
716/// # Examples
717/// ```
718/// use malachite_base::num::basic::traits::NegativeInfinity;
719/// use malachite_float::float::arithmetic::cbrt::primitive_float_cbrt;
720///
721/// assert!(primitive_float_cbrt::<f64>(f64::NAN).is_nan());
722/// assert_eq!(primitive_float_cbrt::<f64>(f64::INFINITY), f64::INFINITY);
723/// assert_eq!(
724///     primitive_float_cbrt::<f64>(f64::NEGATIVE_INFINITY),
725///     f64::NEGATIVE_INFINITY
726/// );
727/// assert_eq!(primitive_float_cbrt::<f64>(27.0), 3.0);
728/// assert_eq!(primitive_float_cbrt::<f64>(-8.0), -2.0);
729/// ```
730#[inline]
731#[allow(clippy::type_repetition_in_bounds)]
732pub fn primitive_float_cbrt<T: PrimitiveFloat>(x: T) -> T
733where
734    Float: From<T> + PartialOrd<T>,
735    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
736{
737    primitive_float_root_u(x, 3)
738}
739
740/// Takes the cube root of a [`Rational`], returning a correctly-rounded primitive float.
741///
742/// The returned primitive float is the one closest to the real cube root of the input, with ties
743/// rounded to even.
744///
745/// $$
746/// f(x) = \sqrt\[3\]{x}.
747/// $$
748///
749/// # Worst-case complexity
750/// $T(n) = O(n \log n \log\log n)$
751///
752/// $M(n) = O(n \log n)$
753///
754/// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
755///
756/// # Examples
757/// ```
758/// use malachite_float::float::arithmetic::cbrt::primitive_float_cbrt_rational;
759/// use malachite_q::Rational;
760///
761/// assert_eq!(
762///     primitive_float_cbrt_rational::<f64>(&Rational::from(27)),
763///     3.0
764/// );
765/// assert_eq!(
766///     primitive_float_cbrt_rational::<f64>(&Rational::from(-8)),
767///     -2.0
768/// );
769/// ```
770#[inline]
771#[allow(clippy::type_repetition_in_bounds)]
772pub fn primitive_float_cbrt_rational<T: PrimitiveFloat>(x: &Rational) -> T
773where
774    Float: PartialOrd<T>,
775    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
776{
777    primitive_float_root_u_rational(x, 3)
778}