malachite_float/arithmetic/
square.rs

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