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}