Skip to main content

malachite_float/float/arithmetic/
square.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::InnerFloat::{Finite, Infinity, NaN, Zero};
10use crate::{
11    Float, float_either_infinity, float_either_zero, float_infinity, float_nan, float_zero,
12};
13use core::cmp::Ordering::{self, *};
14use malachite_base::num::arithmetic::traits::{
15    ArithmeticCheckedShl, IsPowerOf2, Square, SquareAssign,
16};
17use malachite_base::num::logic::traits::SignificantBits;
18use malachite_base::rounding_modes::RoundingMode::{self, *};
19use malachite_nz::natural::arithmetic::float::square::{
20    square_float_significand_in_place, square_float_significand_ref,
21};
22
23impl Float {
24    /// Squares a [`Float`], rounding the result to the specified precision and with the specified
25    /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
26    /// whether the rounded square is less than, equal to, or greater than the exact square.
27    /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
28    /// it also returns `Equal`.
29    ///
30    /// See [`RoundingMode`] for a description of the possible rounding modes.
31    ///
32    /// $$
33    /// f(x,p,m) = x^2+\varepsilon.
34    /// $$
35    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
36    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
37    ///   2^{\lfloor\log_2 |x^2|\rfloor-p+1}$.
38    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
39    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$.
40    ///
41    /// If the output has a precision, it is `prec`.
42    ///
43    /// Special cases:
44    /// - $f(\text{NaN},p,m)=\text{NaN}$
45    /// - $f(\pm\infty,p,m)=\infty$
46    /// - $f(\pm0.0,p,m)=0.0$
47    ///
48    /// Overflow and underflow:
49    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
50    ///   returned instead.
51    /// - 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
52    ///   returned instead, where `p` is the precision of the input.
53    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
54    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
55    ///   instead.
56    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
57    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
58    ///   instead.
59    ///
60    /// Since the result is never negative, negative overflow and underflow cannot occur.
61    ///
62    /// If you know you'll be using `Nearest`, consider using [`Float::square_prec`] instead. If you
63    /// know that your target precision is the precision of the input, consider using
64    /// [`Float::square_round`] instead. If both of these things are true, consider using
65    /// [`Float::square`] instead.
66    ///
67    /// # Worst-case complexity
68    /// $T(n, m) = O(n \log n \log\log n + m)$
69    ///
70    /// $M(n, m) = O(n \log n + m)$
71    ///
72    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
73    /// `prec`.
74    ///
75    /// # Panics
76    /// Panics if `rm` is `Exact` but `prec` is too small for an exact squaring.
77    ///
78    /// # Examples
79    /// ```
80    /// use core::f64::consts::PI;
81    /// use malachite_base::rounding_modes::RoundingMode::*;
82    /// use malachite_float::Float;
83    /// use std::cmp::Ordering::*;
84    ///
85    /// let (square, o) = Float::from(PI).square_prec_round(5, Floor);
86    /// assert_eq!(square.to_string(), "9.50");
87    /// assert_eq!(o, Less);
88    ///
89    /// let (square, o) = Float::from(PI).square_prec_round(5, Ceiling);
90    /// assert_eq!(square.to_string(), "10.0");
91    /// assert_eq!(o, Greater);
92    ///
93    /// let (square, o) = Float::from(PI).square_prec_round(5, Nearest);
94    /// assert_eq!(square.to_string(), "10.0");
95    /// assert_eq!(o, Greater);
96    ///
97    /// let (square, o) = Float::from(PI).square_prec_round(20, Floor);
98    /// assert_eq!(square.to_string(), "9.8695984");
99    /// assert_eq!(o, Less);
100    ///
101    /// let (square, o) = Float::from(PI).square_prec_round(20, Ceiling);
102    /// assert_eq!(square.to_string(), "9.8696136");
103    /// assert_eq!(o, Greater);
104    ///
105    /// let (square, o) = Float::from(PI).square_prec_round(20, Nearest);
106    /// assert_eq!(square.to_string(), "9.8695984");
107    /// assert_eq!(o, Less);
108    /// ```
109    #[inline]
110    pub fn square_prec_round(mut self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
111        let o = self.square_prec_round_assign(prec, rm);
112        (self, o)
113    }
114
115    /// Squares a [`Float`], rounding the result to the specified precision and with the specified
116    /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
117    /// indicating whether the rounded square is less than, equal to, or greater than the exact
118    /// square. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
119    /// a `NaN` it also returns `Equal`.
120    ///
121    /// See [`RoundingMode`] for a description of the possible rounding modes.
122    ///
123    /// $$
124    /// f(x,p,m) = x^2+\varepsilon.
125    /// $$
126    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
127    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
128    ///   2^{\lfloor\log_2 |x^2|\rfloor-p+1}$.
129    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
130    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$.
131    ///
132    /// If the output has a precision, it is `prec`.
133    ///
134    /// Special cases:
135    /// - $f(\text{NaN},p,m)=\text{NaN}$
136    /// - $f(\pm\infty,p,m)=\infty$
137    /// - $f(\pm0.0,p,m)=0.0$
138    ///
139    /// Overflow and underflow:
140    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
141    ///   returned instead.
142    /// - 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
143    ///   returned instead, where `p` is the precision of the input.
144    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
145    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
146    ///   instead.
147    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
148    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
149    ///   instead.
150    ///
151    /// Since the result is never negative, negative overflow and underflow cannot occur.
152    ///
153    /// If you know you'll be using `Nearest`, consider using [`Float::square_prec_ref`] instead. If
154    /// you know that your target precision is the precision of the input, consider using
155    /// [`Float::square_round_ref`] instead. If both of these things are true, consider using
156    /// `(&Float).square()`instead.
157    ///
158    /// # Worst-case complexity
159    /// $T(n, m) = O(n \log n \log\log n + m)$
160    ///
161    /// $M(n, m) = O(n \log n + m)$
162    ///
163    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
164    /// `prec`.
165    ///
166    /// # Panics
167    /// Panics if `rm` is `Exact` but `prec` is too small for an exact squaring.
168    ///
169    /// # Examples
170    /// ```
171    /// use core::f64::consts::PI;
172    /// use malachite_base::rounding_modes::RoundingMode::*;
173    /// use malachite_float::Float;
174    /// use std::cmp::Ordering::*;
175    ///
176    /// let (square, o) = Float::from(PI).square_prec_round_ref(5, Floor);
177    /// assert_eq!(square.to_string(), "9.50");
178    /// assert_eq!(o, Less);
179    ///
180    /// let (square, o) = Float::from(PI).square_prec_round_ref(5, Ceiling);
181    /// assert_eq!(square.to_string(), "10.0");
182    /// assert_eq!(o, Greater);
183    ///
184    /// let (square, o) = Float::from(PI).square_prec_round_ref(5, Nearest);
185    /// assert_eq!(square.to_string(), "10.0");
186    /// assert_eq!(o, Greater);
187    ///
188    /// let (square, o) = Float::from(PI).square_prec_round_ref(20, Floor);
189    /// assert_eq!(square.to_string(), "9.8695984");
190    /// assert_eq!(o, Less);
191    ///
192    /// let (square, o) = Float::from(PI).square_prec_round_ref(20, Ceiling);
193    /// assert_eq!(square.to_string(), "9.8696136");
194    /// assert_eq!(o, Greater);
195    ///
196    /// let (square, o) = Float::from(PI).square_prec_round_ref(20, Nearest);
197    /// assert_eq!(square.to_string(), "9.8695984");
198    /// assert_eq!(o, Less);
199    /// ```
200    #[inline]
201    pub fn square_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
202        assert_ne!(prec, 0);
203        match self {
204            float_nan!() => (float_nan!(), Equal),
205            float_either_infinity!() => (float_infinity!(), Equal),
206            float_either_zero!() => (float_zero!(), Equal),
207            Self(Finite {
208                exponent: x_exp,
209                precision: x_prec,
210                significand: x,
211                ..
212            }) => {
213                let twice_exp = x_exp << 1;
214                if twice_exp - 1 > Self::MAX_EXPONENT {
215                    assert!(rm != Exact, "Inexact Float squaring");
216                    return match rm {
217                        Ceiling | Up | Nearest => (float_infinity!(), Greater),
218                        _ => (Self::max_finite_value_with_prec(prec), Less),
219                    };
220                } else if twice_exp < Self::MIN_EXPONENT_MINUS_1 {
221                    assert!(rm != Exact, "Inexact Float squaring");
222                    return match rm {
223                        Floor | Down | Nearest => (float_zero!(), Less),
224                        _ => (Self::min_positive_value_prec(prec), Greater),
225                    };
226                }
227                let (square, exp_offset, o) = square_float_significand_ref(x, *x_prec, prec, rm);
228                let exp = x_exp
229                    .arithmetic_checked_shl(1u32)
230                    .unwrap()
231                    .checked_add(exp_offset)
232                    .unwrap();
233                if exp > Self::MAX_EXPONENT {
234                    assert!(rm != Exact, "Inexact Float squaring");
235                    return match rm {
236                        Ceiling | Up | Nearest => (float_infinity!(), Greater),
237                        _ => (Self::max_finite_value_with_prec(prec), Less),
238                    };
239                } else if exp < Self::MIN_EXPONENT {
240                    return if rm == Nearest
241                        && exp == Self::MIN_EXPONENT_MINUS_1
242                        && (o == Less || !square.is_power_of_2())
243                    {
244                        (Self::min_positive_value_prec(prec), Greater)
245                    } else {
246                        match rm {
247                            Exact => panic!("Inexact float squaring"),
248                            Ceiling | Up => (Self::min_positive_value_prec(prec), Greater),
249                            _ => (float_zero!(), Less),
250                        }
251                    };
252                }
253                (
254                    Self(Finite {
255                        sign: true,
256                        exponent: exp,
257                        precision: prec,
258                        significand: square,
259                    }),
260                    o,
261                )
262            }
263        }
264    }
265
266    /// Squares a [`Float`], rounding the result to the nearest value of the specified precision.
267    /// The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether the
268    /// rounded square is less than, equal to, or greater than the exact square. Although `NaN`s are
269    /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
270    /// `Equal`.
271    ///
272    /// If the square is equidistant from two [`Float`]s with the specified precision, the [`Float`]
273    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
274    /// the `Nearest` rounding mode.
275    ///
276    /// $$
277    /// f(x,p) = x^2+\varepsilon.
278    /// $$
279    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
280    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$.
281    ///
282    /// If the output has a precision, it is `prec`.
283    ///
284    /// Special cases:
285    /// - $f(\text{NaN},p)=\text{NaN}$
286    /// - $f(\pm\infty,p)=\infty$
287    /// - $f(\pm0.0,p)=0.0$
288    ///
289    /// Overflow and underflow:
290    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
291    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
292    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
293    ///
294    /// Since the result is never negative, negative overflow and underflow cannot occur.
295    ///
296    /// If you want to use a rounding mode other than `Nearest`, consider using
297    /// [`Float::square_prec_round`] instead. If you know that your target precision is the
298    /// precision of the input, consider using [`Float::square`] instead.
299    ///
300    /// # Worst-case complexity
301    /// $T(n, m) = O(n \log n \log\log n + m)$
302    ///
303    /// $M(n, m) = O(n \log n + m)$
304    ///
305    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
306    /// `prec`.
307    ///
308    /// # Examples
309    /// ```
310    /// use core::f64::consts::PI;
311    /// use malachite_float::Float;
312    /// use std::cmp::Ordering::*;
313    ///
314    /// let (square, o) = Float::from(PI).square_prec(5);
315    /// assert_eq!(square.to_string(), "10.0");
316    /// assert_eq!(o, Greater);
317    ///
318    /// let (square, o) = Float::from(PI).square_prec(20);
319    /// assert_eq!(square.to_string(), "9.8695984");
320    /// assert_eq!(o, Less);
321    /// ```
322    #[inline]
323    pub fn square_prec(self, prec: u64) -> (Self, Ordering) {
324        self.square_prec_round(prec, Nearest)
325    }
326
327    /// Squares a [`Float`], rounding the result to the nearest value of the specified precision.
328    /// The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating whether
329    /// the rounded square is less than, equal to, or greater than the exact square. Although `NaN`s
330    /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
331    /// `Equal`.
332    ///
333    /// If the square is equidistant from two [`Float`]s with the specified precision, the [`Float`]
334    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
335    /// the `Nearest` rounding mode.
336    ///
337    /// $$
338    /// f(x,p) = x^2+\varepsilon.
339    /// $$
340    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
341    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$.
342    ///
343    /// If the output has a precision, it is `prec`.
344    ///
345    /// Special cases:
346    /// - $f(\text{NaN},p)=\text{NaN}$
347    /// - $f(\pm\infty,p)=\infty$
348    /// - $f(\pm0.0,p)=0.0$
349    ///
350    /// Overflow and underflow:
351    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
352    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
353    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
354    ///
355    /// Since the result is never negative, negative overflow and underflow cannot occur.
356    ///
357    /// If you want to use a rounding mode other than `Nearest`, consider using
358    /// [`Float::square_prec_round_ref`] instead. If you know that your target precision is the
359    /// precision of the input, consider using `(&Float).square()` instead.
360    ///
361    /// # Worst-case complexity
362    /// $T(n, m) = O(n \log n \log\log n + m)$
363    ///
364    /// $M(n, m) = O(n \log n + m)$
365    ///
366    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
367    /// `prec`.
368    ///
369    /// # Examples
370    /// ```
371    /// use core::f64::consts::PI;
372    /// use malachite_float::Float;
373    /// use std::cmp::Ordering::*;
374    ///
375    /// let (square, o) = Float::from(PI).square_prec_ref(5);
376    /// assert_eq!(square.to_string(), "10.0");
377    /// assert_eq!(o, Greater);
378    ///
379    /// let (square, o) = Float::from(PI).square_prec_ref(20);
380    /// assert_eq!(square.to_string(), "9.8695984");
381    /// assert_eq!(o, Less);
382    /// ```
383    #[inline]
384    pub fn square_prec_ref(&self, prec: u64) -> (Self, Ordering) {
385        self.square_prec_round_ref(prec, Nearest)
386    }
387
388    /// Squares a [`Float`], rounding the result with the specified rounding mode. The [`Float`] is
389    /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded square is
390    /// less than, equal to, or greater than the exact square. Although `NaN`s are not comparable to
391    /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
392    ///
393    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
394    /// description of the possible rounding modes.
395    ///
396    /// $$
397    /// f(x,m) = x^2+\varepsilon.
398    /// $$
399    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
400    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
401    ///   2^{\lfloor\log_2 |x^2|\rfloor-p+1}$, where $p$ is the precision of the input.
402    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
403    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$, where $p$ is the precision of the input.
404    ///
405    /// If the output has a precision, it is the precision of the input.
406    ///
407    /// Special cases:
408    /// - $f(\text{NaN},m)=\text{NaN}$
409    /// - $f(\pm\infty,m)=\infty$
410    /// - $f(\pm0.0,m)=0.0$
411    ///
412    /// Overflow and underflow:
413    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
414    ///   returned instead.
415    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
416    ///   returned instead, where `p` is the precision of the input.
417    /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
418    /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
419    ///   instead.
420    /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
421    /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
422    ///   instead.
423    ///
424    /// Since the result is never negative, negative overflow and underflow cannot occur.
425    ///
426    /// If you want to specify an output precision, consider using [`Float::square_prec_round`]
427    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
428    /// [`Float::square`] instead.
429    ///
430    /// # Worst-case complexity
431    /// $T(n) = O(n \log n \log\log n)$
432    ///
433    /// $M(n) = O(n \log n)$
434    ///
435    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
436    ///
437    /// # Panics
438    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
439    /// output.
440    ///
441    /// # Examples
442    /// ```
443    /// use core::f64::consts::PI;
444    /// use malachite_base::rounding_modes::RoundingMode::*;
445    /// use malachite_float::Float;
446    /// use std::cmp::Ordering::*;
447    ///
448    /// let (square, o) = Float::from(PI).square_round(Floor);
449    /// assert_eq!(square.to_string(), "9.8696044010893473");
450    /// assert_eq!(o, Less);
451    ///
452    /// let (square, o) = Float::from(PI).square_round(Ceiling);
453    /// assert_eq!(square.to_string(), "9.8696044010893615");
454    /// assert_eq!(o, Greater);
455    ///
456    /// let (square, o) = Float::from(PI).square_round(Nearest);
457    /// assert_eq!(square.to_string(), "9.8696044010893615");
458    /// assert_eq!(o, Greater);
459    /// ```
460    #[inline]
461    pub fn square_round(self, rm: RoundingMode) -> (Self, Ordering) {
462        let prec = self.significant_bits();
463        self.square_prec_round(prec, rm)
464    }
465
466    /// Squares a [`Float`], rounding the result with the specified rounding mode. The [`Float`] is
467    /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded square
468    /// is less than, equal to, or greater than the exact square. Although `NaN`s are not comparable
469    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
470    ///
471    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
472    /// description of the possible rounding modes.
473    ///
474    /// $$
475    /// f(x,m) = x^2+\varepsilon.
476    /// $$
477    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
478    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
479    ///   2^{\lfloor\log_2 |x^2|\rfloor-p+1}$, where $p$ is the precision of the input.
480    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
481    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$, where $p$ is the precision of the input.
482    ///
483    /// If the output has a precision, it is the precision of the input.
484    ///
485    /// Special cases:
486    /// - $f(\text{NaN},m)=\text{NaN}$
487    /// - $f(\pm\infty,m)=\infty$
488    /// - $f(\pm0.0,m)=0.0$
489    ///
490    /// Overflow and underflow:
491    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
492    ///   returned instead.
493    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
494    ///   returned instead, where `p` is the precision of the input.
495    /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
496    /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
497    ///   instead.
498    /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
499    /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
500    ///   instead.
501    ///
502    /// Since the result is never negative, negative overflow and underflow cannot occur.
503    ///
504    /// If you want to specify an output precision, consider using [`Float::square_prec_round_ref`]
505    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
506    /// `(&Float).square()` instead.
507    ///
508    /// # Worst-case complexity
509    /// $T(n) = O(n \log n \log\log n)$
510    ///
511    /// $M(n) = O(n \log n)$
512    ///
513    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
514    ///
515    /// # Panics
516    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
517    /// output.
518    ///
519    /// # Examples
520    /// ```
521    /// use core::f64::consts::PI;
522    /// use malachite_base::rounding_modes::RoundingMode::*;
523    /// use malachite_float::Float;
524    /// use std::cmp::Ordering::*;
525    ///
526    /// let (square, o) = Float::from(PI).square_round_ref(Floor);
527    /// assert_eq!(square.to_string(), "9.8696044010893473");
528    /// assert_eq!(o, Less);
529    ///
530    /// let (square, o) = Float::from(PI).square_round_ref(Ceiling);
531    /// assert_eq!(square.to_string(), "9.8696044010893615");
532    /// assert_eq!(o, Greater);
533    ///
534    /// let (square, o) = Float::from(PI).square_round_ref(Nearest);
535    /// assert_eq!(square.to_string(), "9.8696044010893615");
536    /// assert_eq!(o, Greater);
537    /// ```
538    #[inline]
539    pub fn square_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
540        let prec = self.significant_bits();
541        self.square_prec_round_ref(prec, rm)
542    }
543
544    /// Squares a [`Float`] in place, rounding the result to the specified precision and with the
545    /// specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded square
546    /// is less than, equal to, or greater than the exact square. Although `NaN`s are not comparable
547    /// to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns
548    /// `Equal`.
549    ///
550    /// See [`RoundingMode`] for a description of the possible rounding modes.
551    ///
552    /// $$
553    /// x \gets x^2+\varepsilon.
554    /// $$
555    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
556    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
557    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
558    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
559    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$.
560    ///
561    /// If the output has a precision, it is `prec`.
562    ///
563    /// See the [`Float::square_prec_round`] documentation for information on special cases,
564    /// overflow, and underflow.
565    ///
566    /// If you know you'll be using `Nearest`, consider using [`Float::square_prec_assign`] instead.
567    /// If you know that your target precision is the precision of the input, consider using
568    /// [`Float::square_round_assign`] instead. If both of these things are true, consider using
569    /// [`Float::square_assign`] instead.
570    ///
571    /// # Worst-case complexity
572    /// $T(n, m) = O(n \log n \log\log n + m)$
573    ///
574    /// $M(n, m) = O(n \log n + m)$
575    ///
576    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
577    /// `prec`.
578    ///
579    /// # Panics
580    /// Panics if `rm` is `Exact` but `prec` is too small for an exact squaring;
581    ///
582    /// # Examples
583    /// ```
584    /// use core::f64::consts::PI;
585    /// use malachite_base::rounding_modes::RoundingMode::*;
586    /// use malachite_float::Float;
587    /// use std::cmp::Ordering::*;
588    ///
589    /// let mut x = Float::from(PI);
590    /// assert_eq!(x.square_prec_round_assign(5, Floor), Less);
591    /// assert_eq!(x.to_string(), "9.50");
592    ///
593    /// let mut x = Float::from(PI);
594    /// assert_eq!(x.square_prec_round_assign(5, Ceiling), Greater);
595    /// assert_eq!(x.to_string(), "10.0");
596    ///
597    /// let mut x = Float::from(PI);
598    /// assert_eq!(x.square_prec_round_assign(5, Nearest), Greater);
599    /// assert_eq!(x.to_string(), "10.0");
600    ///
601    /// let mut x = Float::from(PI);
602    /// assert_eq!(x.square_prec_round_assign(20, Floor), Less);
603    /// assert_eq!(x.to_string(), "9.8695984");
604    ///
605    /// let mut x = Float::from(PI);
606    /// assert_eq!(x.square_prec_round_assign(20, Ceiling), Greater);
607    /// assert_eq!(x.to_string(), "9.8696136");
608    ///
609    /// let mut x = Float::from(PI);
610    /// assert_eq!(x.square_prec_round_assign(20, Nearest), Less);
611    /// assert_eq!(x.to_string(), "9.8695984");
612    /// ```
613    #[inline]
614    pub fn square_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
615        assert_ne!(prec, 0);
616        match self {
617            float_nan!() => Equal,
618            Self(Infinity { sign } | Zero { sign }) => {
619                *sign = true;
620                Equal
621            }
622            Self(Finite {
623                sign: x_sign,
624                exponent: x_exp,
625                precision: x_prec,
626                significand: x,
627            }) => {
628                let twice_exp = *x_exp << 1;
629                if twice_exp - 1 > Self::MAX_EXPONENT {
630                    assert!(rm != Exact, "Inexact Float squaring");
631                    return match rm {
632                        Ceiling | Up | Nearest => {
633                            *self = float_infinity!();
634                            Greater
635                        }
636                        _ => {
637                            *self = Self::max_finite_value_with_prec(prec);
638                            Less
639                        }
640                    };
641                } else if twice_exp < Self::MIN_EXPONENT_MINUS_1 {
642                    assert!(rm != Exact, "Inexact Float squaring");
643                    return match rm {
644                        Floor | Down | Nearest => {
645                            *self = float_zero!();
646                            Less
647                        }
648                        _ => {
649                            *self = Self::min_positive_value_prec(prec);
650                            Greater
651                        }
652                    };
653                }
654                let (exp_offset, o) = square_float_significand_in_place(x, *x_prec, prec, rm);
655                *x_exp = x_exp
656                    .arithmetic_checked_shl(1u32)
657                    .unwrap()
658                    .checked_add(exp_offset)
659                    .unwrap();
660                if *x_exp > Self::MAX_EXPONENT {
661                    assert!(rm != Exact, "Inexact Float squaring");
662                    return match rm {
663                        Ceiling | Up | Nearest => {
664                            *self = float_infinity!();
665                            Greater
666                        }
667                        _ => {
668                            *self = Self::max_finite_value_with_prec(prec);
669                            Less
670                        }
671                    };
672                } else if *x_exp < Self::MIN_EXPONENT {
673                    return if rm == Nearest
674                        && *x_exp == Self::MIN_EXPONENT_MINUS_1
675                        && (o == Less || !x.is_power_of_2())
676                    {
677                        {
678                            *self = Self::min_positive_value_prec(prec);
679                            Greater
680                        }
681                    } else {
682                        match rm {
683                            Exact => panic!("Inexact float squaring"),
684                            Ceiling | Up => {
685                                *self = Self::min_positive_value_prec(prec);
686                                Greater
687                            }
688                            _ => {
689                                *self = float_zero!();
690                                Less
691                            }
692                        }
693                    };
694                }
695                *x_sign = true;
696                *x_prec = prec;
697                o
698            }
699        }
700    }
701
702    /// Squares a [`Float`] in place, rounding the result to the nearest value of the specified
703    /// precision. An [`Ordering`] is returned, indicating whether the rounded square is less than,
704    /// equal to, or greater than the exact square. Although `NaN`s are not comparable to any
705    /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
706    ///
707    /// If the square is equidistant from two [`Float`]s with the specified precision, the [`Float`]
708    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
709    /// the `Nearest` rounding mode.
710    ///
711    /// $$
712    /// x \gets x^2+\varepsilon.
713    /// $$
714    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
715    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$.
716    ///
717    /// If the output has a precision, it is `prec`.
718    ///
719    /// See the [`Float::square_prec`] documentation for information on special cases, overflow, and
720    /// underflow.
721    ///
722    /// If you want to use a rounding mode other than `Nearest`, consider using
723    /// [`Float::square_prec_round_assign`] instead. If you know that your target precision is the
724    /// precision of the input, consider using [`Float::square`] instead.
725    ///
726    /// # Worst-case complexity
727    /// $T(n, m) = O(n \log n \log\log n + m)$
728    ///
729    /// $M(n, m) = O(n \log n + m)$
730    ///
731    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
732    /// `prec`.
733    ///
734    /// # Examples
735    /// ```
736    /// use core::f64::consts::PI;
737    /// use malachite_float::Float;
738    /// use std::cmp::Ordering::*;
739    ///
740    /// let mut x = Float::from(PI);
741    /// assert_eq!(x.square_prec_assign(5), Greater);
742    /// assert_eq!(x.to_string(), "10.0");
743    ///
744    /// let mut x = Float::from(PI);
745    /// assert_eq!(x.square_prec_assign(20), Less);
746    /// assert_eq!(x.to_string(), "9.8695984");
747    /// ```
748    #[inline]
749    pub fn square_prec_assign(&mut self, prec: u64) -> Ordering {
750        self.square_prec_round_assign(prec, Nearest)
751    }
752
753    /// Squares a [`Float`] in place, rounding the result with the specified rounding mode. An
754    /// [`Ordering`] is returned, indicating whether the rounded square is less than, equal to, or
755    /// greater than the exact square. Although `NaN`s are not comparable to any [`Float`], whenever
756    /// this function sets the [`Float`] to `NaN` it also returns `Equal`.
757    ///
758    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
759    /// description of the possible rounding modes.
760    ///
761    /// $$
762    /// x \gets x^2+\varepsilon.
763    /// $$
764    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
765    /// - If $x^2$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
766    ///   2^{\lfloor\log_2 |x^2|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
767    /// - If $x^2$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
768    ///   2^{\lfloor\log_2 |x^2|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
769    ///
770    /// If the output has a precision, it is the precision of the input.
771    ///
772    /// See the [`Float::square_round`] documentation for information on special cases, overflow,
773    /// and underflow.
774    ///
775    /// If you want to specify an output precision, consider using
776    /// [`Float::square_prec_round_assign`] instead. If you know you'll be using the `Nearest`
777    /// rounding mode, consider using [`Float::square_assign`] instead.
778    ///
779    /// # Worst-case complexity
780    /// $T(n) = O(n \log n \log\log n)$
781    ///
782    /// $M(n) = O(n \log n)$
783    ///
784    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
785    ///
786    /// # Panics
787    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
788    /// output.
789    ///
790    /// # Examples
791    /// ```
792    /// use core::f64::consts::PI;
793    /// use malachite_base::rounding_modes::RoundingMode::*;
794    /// use malachite_float::Float;
795    /// use std::cmp::Ordering::*;
796    ///
797    /// let mut x = Float::from(PI);
798    /// assert_eq!(x.square_round_assign(Floor), Less);
799    /// assert_eq!(x.to_string(), "9.8696044010893473");
800    ///
801    /// let mut x = Float::from(PI);
802    /// assert_eq!(x.square_round_assign(Ceiling), Greater);
803    /// assert_eq!(x.to_string(), "9.8696044010893615");
804    ///
805    /// let mut x = Float::from(PI);
806    /// assert_eq!(x.square_round_assign(Nearest), Greater);
807    /// assert_eq!(x.to_string(), "9.8696044010893615");
808    /// ```
809    #[inline]
810    pub fn square_round_assign(&mut self, rm: RoundingMode) -> Ordering {
811        let prec = self.significant_bits();
812        self.square_prec_round_assign(prec, rm)
813    }
814}
815
816impl Square for Float {
817    type Output = Self;
818
819    /// Squares a [`Float`], taking it by value.
820    ///
821    /// If the output has a precision, it is the precision of the input. If the square is
822    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
823    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
824    /// rounding mode.
825    ///
826    /// $$
827    /// f(x) = x^2+\varepsilon.
828    /// $$
829    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
830    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$,
831    ///   where $p$ is the maximum precision of the inputs.
832    ///
833    /// Special cases:
834    /// - $f(\text{NaN})=\text{NaN}$
835    /// - $f(\pm\infty)=\infty$
836    /// - $f(\pm0.0)=0.0$
837    ///
838    /// Overflow and underflow:
839    /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
840    /// - If $0<f(x)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
841    /// - If $2^{-2^{30}-1}<f(x)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
842    ///
843    /// Since the result is never negative, negative overflow and underflow cannot occur.
844    ///
845    /// If you want to use a rounding mode other than `Nearest`, consider using
846    /// [`Float::square_prec`] instead. If you want to specify the output precision, consider using
847    /// [`Float::square_round`]. If you want both of these things, consider using
848    /// [`Float::square_prec_round`].
849    ///
850    /// # Worst-case complexity
851    /// $T(n) = O(n \log n \log\log n)$
852    ///
853    /// $M(n) = O(n \log n)$
854    ///
855    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
856    ///
857    /// # Examples
858    /// ```
859    /// use malachite_base::num::arithmetic::traits::Square;
860    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
861    /// use malachite_float::Float;
862    ///
863    /// assert!(Float::NAN.square().is_nan());
864    /// assert_eq!(Float::INFINITY.square(), Float::INFINITY);
865    /// assert_eq!(Float::NEGATIVE_INFINITY.square(), Float::INFINITY);
866    /// assert_eq!(Float::from(1.5).square(), 2.0);
867    /// assert_eq!(Float::from(-1.5).square(), 2.0);
868    /// ```
869    #[inline]
870    fn square(self) -> Self {
871        let prec = self.significant_bits();
872        self.square_prec_round(prec, Nearest).0
873    }
874}
875
876impl Square for &Float {
877    type Output = Float;
878
879    /// Squares a [`Float`], taking it by reference.
880    ///
881    /// If the output has a precision, it is the precision of the input. If the square is
882    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
883    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
884    /// rounding mode.
885    ///
886    /// $$
887    /// f(x) = x^2+\varepsilon.
888    /// $$
889    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
890    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$,
891    ///   where $p$ is the maximum precision of the inputs.
892    ///
893    /// Special cases:
894    /// - $f(\text{NaN})=\text{NaN}$
895    /// - $f(\pm\infty)=\infty$
896    /// - $f(\pm0.0)=0.0$
897    ///
898    /// Overflow and underflow:
899    /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
900    /// - If $0<f(x)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
901    /// - If $2^{-2^{30}-1}<f(x)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
902    ///
903    /// Since the result is never negative, negative overflow and underflow cannot occur.
904    ///
905    /// If you want to use a rounding mode other than `Nearest`, consider using
906    /// [`Float::square_prec_ref`] instead. If you want to specify the output precision, consider
907    /// using [`Float::square_round_ref`]. If you want both of these things, consider using
908    /// [`Float::square_prec_round_ref`].
909    ///
910    /// # Worst-case complexity
911    /// $T(n) = O(n \log n \log\log n)$
912    ///
913    /// $M(n) = O(n \log n)$
914    ///
915    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
916    ///
917    /// # Examples
918    /// ```
919    /// use malachite_base::num::arithmetic::traits::Square;
920    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
921    /// use malachite_float::Float;
922    ///
923    /// assert!((&Float::NAN).square().is_nan());
924    /// assert_eq!((&Float::INFINITY).square(), Float::INFINITY);
925    /// assert_eq!((&Float::NEGATIVE_INFINITY).square(), Float::INFINITY);
926    /// assert_eq!((&Float::from(1.5)).square(), 2.0);
927    /// assert_eq!((&Float::from(-1.5)).square(), 2.0);
928    /// ```
929    #[inline]
930    fn square(self) -> Float {
931        let prec = self.significant_bits();
932        self.square_prec_round_ref(prec, Nearest).0
933    }
934}
935
936impl SquareAssign for Float {
937    /// Squares a [`Float`] in place.
938    ///
939    /// If the output has a precision, it is the precision of the input. If the square is
940    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
941    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
942    /// rounding mode.
943    ///
944    /// $$
945    /// x\gets = x^2+\varepsilon.
946    /// $$
947    /// - If $x^2$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
948    /// - If $x^2$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |x^2|\rfloor-p}$,
949    ///   where $p$ is the maximum precision of the inputs.
950    ///
951    /// See the [`Float::square`] documentation for information on special cases, overflow, and
952    /// underflow.
953    ///
954    /// If you want to use a rounding mode other than `Nearest`, consider using
955    /// [`Float::square_prec_assign`] instead. If you want to specify the output precision, consider
956    /// using [`Float::square_round_assign`]. If you want both of these things, consider using
957    /// [`Float::square_prec_round_assign`].
958    ///
959    /// # Worst-case complexity
960    /// $T(n) = O(n \log n \log\log n)$
961    ///
962    /// $M(n) = O(n \log n)$
963    ///
964    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
965    ///
966    /// # Examples
967    /// ```
968    /// use malachite_base::num::arithmetic::traits::SquareAssign;
969    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
970    /// use malachite_float::Float;
971    ///
972    /// let mut x = Float::NAN;
973    /// x.square_assign();
974    /// assert!(x.is_nan());
975    ///
976    /// let mut x = Float::INFINITY;
977    /// x.square_assign();
978    /// assert_eq!(x, Float::INFINITY);
979    ///
980    /// let mut x = Float::NEGATIVE_INFINITY;
981    /// x.square_assign();
982    /// assert_eq!(x, Float::INFINITY);
983    ///
984    /// let mut x = Float::from(1.5);
985    /// x.square_assign();
986    /// assert_eq!(x, 2.0);
987    ///
988    /// let mut x = Float::from(-1.5);
989    /// x.square_assign();
990    /// assert_eq!(x, 2.0);
991    /// ```
992    #[inline]
993    fn square_assign(&mut self) {
994        let prec = self.significant_bits();
995        self.square_prec_round_assign(prec, Nearest);
996    }
997}