malachite_base/num/arithmetic/
sqrt.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      `mpn_sqrtrem1` contributed to the GNU project by Torbjörn Granlund.
6//
7//      Copyright © 1999-2002, 2004, 2005, 2008, 2010, 2012, 2015, 2017 Free Software Foundation,
8//      Inc.
9//
10// Uses code adopted from the FLINT Library.
11//
12//      Copyright © 2009 William Hart
13//
14// This file is part of Malachite.
15//
16// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
17// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
18// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
19
20use crate::num::arithmetic::traits::{
21    CeilingSqrt, CeilingSqrtAssign, CheckedSqrt, FloorSqrt, FloorSqrtAssign, Ln,
22    RoundToMultipleOfPowerOf2, ShrRound, Sqrt, SqrtAssign, SqrtAssignRem, SqrtRem,
23};
24use crate::num::basic::integers::{PrimitiveInt, USIZE_IS_U32};
25use crate::num::basic::signeds::PrimitiveSigned;
26use crate::num::basic::unsigneds::PrimitiveUnsigned;
27use crate::num::conversion::traits::WrappingFrom;
28use crate::num::logic::traits::SignificantBits;
29use crate::rounding_modes::RoundingMode::*;
30use core::cmp::Ordering::*;
31
32const U8_SQUARES: [u8; 16] = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225];
33
34impl FloorSqrt for u8 {
35    type Output = u8;
36
37    /// Returns the floor of the square root of a [`u8`].
38    ///
39    /// $f(x) = \lfloor\sqrt{x}\rfloor$.
40    ///
41    /// # Worst-case complexity
42    /// Constant time and additional memory.
43    ///
44    /// # Examples
45    /// See [here](super::sqrt#floor_sqrt).
46    ///
47    /// # Notes
48    /// The [`u8`] implementation uses a lookup table.
49    fn floor_sqrt(self) -> u8 {
50        u8::wrapping_from(match U8_SQUARES.binary_search(&self) {
51            Ok(i) => i,
52            Err(i) => i - 1,
53        })
54    }
55}
56
57impl CeilingSqrt for u8 {
58    type Output = u8;
59
60    /// Returns the ceiling of the square root of a [`u8`].
61    ///
62    /// $f(x) = \lceil\sqrt{x}\rceil$.
63    ///
64    /// # Worst-case complexity
65    /// Constant time and additional memory.
66    ///
67    /// # Examples
68    /// See [here](super::sqrt#ceiling_sqrt).
69    ///
70    /// # Notes
71    /// The [`u8`] implementation uses a lookup table.
72    fn ceiling_sqrt(self) -> u8 {
73        u8::wrapping_from(match U8_SQUARES.binary_search(&self) {
74            Ok(i) | Err(i) => i,
75        })
76    }
77}
78
79impl CheckedSqrt for u8 {
80    type Output = u8;
81
82    /// Returns the the square root of a [`u8`], or `None` if the [`u8`] is not a perfect square.
83    ///
84    /// $$
85    /// f(x) = \\begin{cases}
86    ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
87    ///     \operatorname{None} & \textrm{otherwise}.
88    /// \\end{cases}
89    /// $$
90    ///
91    /// # Worst-case complexity
92    /// Constant time and additional memory.
93    ///
94    /// # Examples
95    /// See [here](super::sqrt#checked_sqrt).
96    ///
97    /// # Notes
98    /// The [`u8`] implementation uses a lookup table.
99    fn checked_sqrt(self) -> Option<u8> {
100        U8_SQUARES.binary_search(&self).ok().map(u8::wrapping_from)
101    }
102}
103
104impl SqrtRem for u8 {
105    type SqrtOutput = u8;
106    type RemOutput = u8;
107
108    /// Returns the floor of the square root of a [`u8`], and the remainder (the difference between
109    /// the [`u8`] and the square of the floor).
110    ///
111    /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$.
112    ///
113    /// # Worst-case complexity
114    /// Constant time and additional memory.
115    ///
116    /// # Examples
117    /// See [here](super::sqrt#sqrt_rem).
118    ///
119    /// # Notes
120    /// The [`u8`] implementation uses a lookup table.
121    fn sqrt_rem(self) -> (u8, u8) {
122        match U8_SQUARES.binary_search(&self) {
123            Ok(i) => (u8::wrapping_from(i), 0),
124            Err(i) => (u8::wrapping_from(i - 1), self - U8_SQUARES[i - 1]),
125        }
126    }
127}
128
129pub(crate) fn floor_inverse_checked_binary<T: PrimitiveUnsigned, F: Fn(T) -> Option<T>>(
130    f: F,
131    x: T,
132    mut low: T,
133    mut high: T,
134) -> T {
135    loop {
136        if high <= low {
137            return low;
138        }
139        let mid: T = low.checked_add(high).unwrap().shr_round(1, Ceiling).0;
140        match f(mid).map(|mid| mid.cmp(&x)) {
141            Some(Equal) => return mid,
142            Some(Less) => low = mid,
143            Some(Greater) | None => high = mid - T::ONE,
144        }
145    }
146}
147
148pub_test! {floor_sqrt_binary<T: PrimitiveUnsigned>(x: T) -> T {
149    if x < T::TWO {
150        x
151    } else {
152        let p = T::power_of_2(x.significant_bits().shr_round(1, Ceiling).0);
153        floor_inverse_checked_binary(T::checked_square, x, p >> 1, p)
154    }
155}}
156
157pub_test! {ceiling_sqrt_binary<T: PrimitiveUnsigned>(x: T) -> T {
158    let floor_sqrt = floor_sqrt_binary(x);
159    if floor_sqrt.square() == x {
160        floor_sqrt
161    } else {
162        floor_sqrt + T::ONE
163    }
164}}
165
166pub_test! {checked_sqrt_binary<T: PrimitiveUnsigned>(x: T) -> Option<T> {
167    let floor_sqrt = floor_sqrt_binary(x);
168    if floor_sqrt.square() == x {
169        Some(floor_sqrt)
170    } else {
171        None
172    }
173}}
174
175pub_test! {sqrt_rem_binary<T: PrimitiveUnsigned>(x: T) -> (T, T) {
176    let floor_sqrt = floor_sqrt_binary(x);
177    (floor_sqrt, x - floor_sqrt.square())
178}}
179
180const INV_SQRT_TAB: [u16; 384] = [
181    0xff, 0xfd, 0xfb, 0xf9, 0xf7, 0xf5, 0xf3, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe9, 0xe7, 0xe5, 0xe4,
182    0xe2, 0xe0, 0xdf, 0xdd, 0xdb, 0xda, 0xd8, 0xd7, 0xd5, 0xd4, 0xd2, 0xd1, 0xcf, 0xce, 0xcc, 0xcb,
183    0xc9, 0xc8, 0xc6, 0xc5, 0xc4, 0xc2, 0xc1, 0xc0, 0xbe, 0xbd, 0xbc, 0xba, 0xb9, 0xb8, 0xb7, 0xb5,
184    0xb4, 0xb3, 0xb2, 0xb0, 0xaf, 0xae, 0xad, 0xac, 0xaa, 0xa9, 0xa8, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3,
185    0xa2, 0xa0, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92,
186    0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83,
187    0x83, 0x82, 0x81, 0x80, 0x7f, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x79, 0x78, 0x77, 0x76,
188    0x76, 0x75, 0x74, 0x73, 0x72, 0x72, 0x71, 0x70, 0x6f, 0x6f, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, 0x6a,
189    0x6a, 0x69, 0x68, 0x68, 0x67, 0x66, 0x66, 0x65, 0x64, 0x64, 0x63, 0x62, 0x62, 0x61, 0x60, 0x60,
190    0x5f, 0x5e, 0x5e, 0x5d, 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x59, 0x58, 0x57, 0x57, 0x56, 0x56,
191    0x55, 0x54, 0x54, 0x53, 0x53, 0x52, 0x52, 0x51, 0x50, 0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4d,
192    0x4c, 0x4b, 0x4b, 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45, 0x44,
193    0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41, 0x40, 0x40, 0x3f, 0x3f, 0x3e, 0x3e, 0x3d, 0x3d, 0x3c,
194    0x3c, 0x3b, 0x3b, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
195    0x35, 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2e,
196    0x2e, 0x2d, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28,
197    0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x22, 0x22,
198    0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1c,
199    0x1c, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17,
200    0x17, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12,
201    0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
202    0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
203    0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04,
204    0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
205];
206
207// This is equivalent to `mpn_sqrtrem1` from `mpn/generic/sqrtrem.c`, GMP 6.2.1, where both the
208// square root and the remainder are returned.
209#[doc(hidden)]
210pub fn sqrt_rem_newton<
211    U: PrimitiveUnsigned + WrappingFrom<S>,
212    S: PrimitiveSigned + WrappingFrom<U>,
213>(
214    n: U,
215) -> (U, U) {
216    let magic = match U::WIDTH {
217        u32::WIDTH => {
218            U::wrapping_from(0x100000u32) // 0xfee6f < MAGIC < 0x29cbc8
219        }
220        u64::WIDTH => {
221            U::wrapping_from(0x10000000000u64) // 0xffe7debbfc < magic < 0x232b1850f410
222        }
223        _ => panic!(),
224    };
225    assert!(n.leading_zeros() < 2);
226    // Use Newton iterations for approximating 1/sqrt(a) instead of sqrt(a), since we can do the
227    // former without division. As part of the last iteration convert from 1/sqrt(a) to sqrt(a).
228    let i: usize = (n >> (U::WIDTH - 9)).wrapping_into(); // extract bits for table lookup
229    let mut inv_sqrt = U::wrapping_from(INV_SQRT_TAB[i - 0x80]);
230    inv_sqrt.set_bit(8); // initial 1/sqrt(a)
231    let mut sqrt: U = match U::WIDTH {
232        u32::WIDTH => {
233            let p = inv_sqrt * (n >> 8);
234            let t: U = p >> 13;
235            let a: U = n << 6;
236            let t = S::wrapping_from(a.wrapping_sub(t.wrapping_square()).wrapping_sub(magic)) >> 8;
237            p.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 7)) >> 16
238        }
239        u64::WIDTH => {
240            let a1 = n >> (U::WIDTH - 33);
241            let t = (S::wrapping_from(0x2000000000000u64 - 0x30000)
242                - S::wrapping_from(a1 * inv_sqrt.square()))
243                >> 16;
244            let a: U = inv_sqrt << 16;
245            inv_sqrt = a.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 18));
246            let p = inv_sqrt * (n >> 24);
247            let t: U = p >> 25;
248            let a: U = n << 14;
249            let t = S::wrapping_from(a.wrapping_sub(t.wrapping_square()).wrapping_sub(magic)) >> 24;
250            p.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 15)) >> 32
251        }
252        _ => unreachable!(),
253    };
254    // x0 is now a full limb approximation of sqrt(a0)
255    let mut square = sqrt.square();
256    if square + (sqrt << 1) < n {
257        square += (sqrt << 1) + U::ONE;
258        sqrt += U::ONE;
259    }
260    (sqrt, n - square)
261}
262
263// Returns (sqrt, r_hi, r_lo) such that [n_lo, n_hi] = sqrt ^ 2 + [r_lo, r_hi].
264//
265// # Worst-case complexity
266// Constant time and additional memory.
267//
268// This is equivalent to `mpn_sqrtrem2` from `mpn/generic/sqrtrem.c`, GMP 6.2.1.
269pub fn sqrt_rem_2_newton<
270    U: PrimitiveUnsigned + WrappingFrom<S>,
271    S: PrimitiveSigned + WrappingFrom<U>,
272>(
273    n_hi: U,
274    n_lo: U,
275) -> (U, bool, U) {
276    assert!(n_hi.leading_zeros() < 2);
277    let (mut sqrt, mut r_lo) = sqrt_rem_newton::<U, S>(n_hi);
278    let prec = U::WIDTH >> 1;
279    let prec_p_1: u64 = prec + 1;
280    let prec_m_1: u64 = prec - 1;
281    // r_lo <= 2 * sqrt < 2 ^ (prec + 1)
282    r_lo = (r_lo << prec_m_1) | (n_lo >> prec_p_1);
283    let mut q = r_lo / sqrt;
284    // q <= 2 ^ prec, if q = 2 ^ prec, reduce the overestimate.
285    q -= q >> prec;
286    // now we have q < 2 ^ prec
287    let u = r_lo - q * sqrt;
288    // now we have (rp_lo << prec + n_lo >> prec) / 2 = q * sqrt + u
289    sqrt = (sqrt << prec) | q;
290    let mut r_hi = (u >> prec_m_1) + U::ONE;
291    r_lo = (u << prec_p_1) | (n_lo.mod_power_of_2(prec_p_1));
292    let q_squared = q.square();
293    if r_lo < q_squared {
294        assert_ne!(r_hi, U::ZERO);
295        r_hi -= U::ONE;
296    }
297    r_lo.wrapping_sub_assign(q_squared);
298    if r_hi == U::ZERO {
299        r_lo.wrapping_add_assign(sqrt);
300        if r_lo < sqrt {
301            r_hi += U::ONE;
302        }
303        sqrt -= U::ONE;
304        r_lo.wrapping_add_assign(sqrt);
305        if r_lo < sqrt {
306            r_hi += U::ONE;
307        }
308    }
309    r_hi -= U::ONE;
310    assert!(r_hi < U::TWO);
311    (sqrt, r_hi == U::ONE, r_lo)
312}
313
314// This is equivalent to `n_sqrt` from `ulong_extras/sqrt.c`, FLINT 2.7.1.
315fn floor_sqrt_approx_and_refine<T: PrimitiveUnsigned, F: Fn(T) -> f64, G: Fn(f64) -> T>(
316    f: F,
317    g: G,
318    max_square: T,
319    x: T,
320) -> T {
321    if x >= max_square {
322        return T::low_mask(T::WIDTH >> 1);
323    }
324    let mut sqrt = g(f(x).sqrt());
325    let mut square = if let Some(square) = sqrt.checked_square() {
326        square
327    } else {
328        // set to max possible sqrt
329        sqrt = T::low_mask(T::WIDTH >> 1);
330        sqrt.square()
331    };
332    match square.cmp(&x) {
333        Equal => sqrt,
334        Less => loop {
335            square = square.checked_add((sqrt << 1) + T::ONE).unwrap();
336            sqrt += T::ONE;
337            match square.cmp(&x) {
338                Equal => return sqrt,
339                Less => {}
340                Greater => return sqrt - T::ONE,
341            }
342        },
343        Greater => loop {
344            square -= (sqrt << 1) - T::ONE;
345            sqrt -= T::ONE;
346            if square <= x {
347                return sqrt;
348            }
349        },
350    }
351}
352
353fn ceiling_sqrt_approx_and_refine<T: PrimitiveUnsigned, F: Fn(T) -> f64, G: Fn(f64) -> T>(
354    f: F,
355    g: G,
356    max_square: T,
357    x: T,
358) -> T {
359    if x > max_square {
360        return T::power_of_2(T::WIDTH >> 1);
361    }
362    let mut sqrt = g(f(x).sqrt());
363    let mut square = if let Some(square) = sqrt.checked_square() {
364        square
365    } else {
366        // set to max possible sqrt
367        sqrt = T::low_mask(T::WIDTH >> 1);
368        sqrt.square()
369    };
370    match square.cmp(&x) {
371        Equal => sqrt,
372        Less => loop {
373            square = square.checked_add((sqrt << 1) + T::ONE).unwrap();
374            sqrt += T::ONE;
375            if square >= x {
376                return sqrt;
377            }
378        },
379        Greater => loop {
380            square -= (sqrt << 1) - T::ONE;
381            sqrt -= T::ONE;
382            match square.cmp(&x) {
383                Equal => return sqrt,
384                Greater => {}
385                Less => return sqrt + T::ONE,
386            }
387        },
388    }
389}
390
391fn checked_sqrt_approx_and_refine<T: PrimitiveUnsigned, F: Fn(T) -> f64, G: Fn(f64) -> T>(
392    f: F,
393    g: G,
394    max_square: T,
395    x: T,
396) -> Option<T> {
397    if x > max_square {
398        return None;
399    }
400    let mut sqrt = g(f(x).sqrt());
401    let mut square = if let Some(square) = sqrt.checked_square() {
402        square
403    } else {
404        // set to max possible sqrt
405        sqrt = T::low_mask(T::WIDTH >> 1);
406        sqrt.square()
407    };
408    match square.cmp(&x) {
409        Equal => Some(sqrt),
410        Less => loop {
411            square = square.checked_add((sqrt << 1) + T::ONE).unwrap();
412            sqrt += T::ONE;
413            match square.cmp(&x) {
414                Equal => return Some(sqrt),
415                Less => {}
416                Greater => return None,
417            }
418        },
419        Greater => loop {
420            square -= (sqrt << 1) - T::ONE;
421            sqrt -= T::ONE;
422            match square.cmp(&x) {
423                Equal => return Some(sqrt),
424                Less => return None,
425                Greater => {}
426            }
427        },
428    }
429}
430
431// This is equivalent to `n_sqrtrem` from `ulong_extras/sqrtrem.c`, FLINT 2.7.1.
432fn sqrt_rem_approx_and_refine<T: PrimitiveUnsigned, F: Fn(T) -> f64, G: Fn(f64) -> T>(
433    f: F,
434    g: G,
435    max_square: T,
436    x: T,
437) -> (T, T) {
438    if x >= max_square {
439        return (T::low_mask(T::WIDTH >> 1), x - max_square);
440    }
441    let mut sqrt = g(f(x).sqrt());
442    let mut square = if let Some(square) = sqrt.checked_square() {
443        square
444    } else {
445        // set to max possible sqrt
446        sqrt = T::low_mask(T::WIDTH >> 1);
447        sqrt.square()
448    };
449    match square.cmp(&x) {
450        Equal => (sqrt, T::ZERO),
451        Less => loop {
452            square = square.checked_add((sqrt << 1) + T::ONE).unwrap();
453            sqrt += T::ONE;
454            match square.cmp(&x) {
455                Equal => return (sqrt, T::ZERO),
456                Less => {}
457                Greater => {
458                    square -= (sqrt << 1) - T::ONE;
459                    sqrt -= T::ONE;
460                    return (sqrt, x - square);
461                }
462            }
463        },
464        Greater => loop {
465            square -= (sqrt << 1) - T::ONE;
466            sqrt -= T::ONE;
467            if square <= x {
468                return (sqrt, x - square);
469            }
470        },
471    }
472}
473
474fn floor_sqrt_newton_helper<
475    U: PrimitiveUnsigned + WrappingFrom<S>,
476    S: PrimitiveSigned + WrappingFrom<U>,
477>(
478    x: U,
479) -> U {
480    if x == U::ZERO {
481        return U::ZERO;
482    }
483    let shift = x
484        .leading_zeros()
485        .round_to_multiple_of_power_of_2(1, Floor)
486        .0;
487    sqrt_rem_newton::<U, S>(x << shift).0 >> (shift >> 1)
488}
489
490fn ceiling_sqrt_newton_helper<
491    U: PrimitiveUnsigned + WrappingFrom<S>,
492    S: PrimitiveSigned + WrappingFrom<U>,
493>(
494    x: U,
495) -> U {
496    if x == U::ZERO {
497        return U::ZERO;
498    }
499    let shift = x
500        .leading_zeros()
501        .round_to_multiple_of_power_of_2(1, Floor)
502        .0;
503    let (mut sqrt, rem) = sqrt_rem_newton::<U, S>(x << shift);
504    sqrt >>= shift >> 1;
505    if rem != U::ZERO {
506        sqrt += U::ONE;
507    }
508    sqrt
509}
510
511fn checked_sqrt_newton_helper<
512    U: PrimitiveUnsigned + WrappingFrom<S>,
513    S: PrimitiveSigned + WrappingFrom<U>,
514>(
515    x: U,
516) -> Option<U> {
517    if x == U::ZERO {
518        return Some(U::ZERO);
519    }
520    let shift = x
521        .leading_zeros()
522        .round_to_multiple_of_power_of_2(1, Floor)
523        .0;
524    let (sqrt, rem) = sqrt_rem_newton::<U, S>(x << shift);
525    if rem == U::ZERO {
526        Some(sqrt >> (shift >> 1))
527    } else {
528        None
529    }
530}
531
532fn sqrt_rem_newton_helper<
533    U: PrimitiveUnsigned + WrappingFrom<S>,
534    S: PrimitiveSigned + WrappingFrom<U>,
535>(
536    x: U,
537) -> (U, U) {
538    if x == U::ZERO {
539        return (U::ZERO, U::ZERO);
540    }
541    let shift = x
542        .leading_zeros()
543        .round_to_multiple_of_power_of_2(1, Floor)
544        .0;
545    let (mut sqrt, rem) = sqrt_rem_newton::<U, S>(x << shift);
546    if shift == 0 {
547        (sqrt, rem)
548    } else {
549        sqrt >>= shift >> 1;
550        (sqrt, x - sqrt.square())
551    }
552}
553
554macro_rules! impl_sqrt_newton {
555    ($u: ident, $s: ident) => {
556        impl FloorSqrt for $u {
557            type Output = $u;
558
559            /// Returns the floor of the square root of an integer.
560            ///
561            /// $f(x) = \lfloor\sqrt{x}\rfloor$.
562            ///
563            /// # Worst-case complexity
564            /// Constant time and additional memory.
565            ///
566            /// # Examples
567            /// See [here](super::sqrt#floor_sqrt).
568            ///
569            /// # Notes
570            /// For [`u32`] and [`u64`], the square root is computed using Newton's method.
571            #[inline]
572            fn floor_sqrt(self) -> $u {
573                floor_sqrt_newton_helper::<$u, $s>(self)
574            }
575        }
576
577        impl CeilingSqrt for $u {
578            type Output = $u;
579
580            /// Returns the ceiling of the square root of an integer.
581            ///
582            /// $f(x) = \lceil\sqrt{x}\rceil$.
583            ///
584            /// # Worst-case complexity
585            /// Constant time and additional memory.
586            ///
587            /// # Examples
588            /// See [here](super::sqrt#ceiling_sqrt).
589            ///
590            /// # Notes
591            /// For [`u32`] and [`u64`], the square root is computed using Newton's method.
592            #[inline]
593            fn ceiling_sqrt(self) -> $u {
594                ceiling_sqrt_newton_helper::<$u, $s>(self)
595            }
596        }
597
598        impl CheckedSqrt for $u {
599            type Output = $u;
600
601            /// Returns the the square root of an integer, or `None` if the integer is not a perfect
602            /// square.
603            ///
604            /// $$
605            /// f(x) = \\begin{cases}
606            ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
607            ///     \operatorname{None} & \textrm{otherwise}.
608            /// \\end{cases}
609            /// $$
610            ///
611            /// # Worst-case complexity
612            /// Constant time and additional memory.
613            ///
614            /// # Examples
615            /// See [here](super::sqrt#checked_sqrt).
616            ///
617            /// # Notes
618            /// For [`u32`] and [`u64`], the square root is computed using Newton's method.
619            #[inline]
620            fn checked_sqrt(self) -> Option<$u> {
621                checked_sqrt_newton_helper::<$u, $s>(self)
622            }
623        }
624
625        impl SqrtRem for $u {
626            type SqrtOutput = $u;
627            type RemOutput = $u;
628
629            /// Returns the floor of the square root of an integer, and the remainder (the
630            /// difference between the integer and the square of the floor).
631            ///
632            /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$.
633            ///
634            /// # Worst-case complexity
635            /// Constant time and additional memory.
636            ///
637            /// # Examples
638            /// See [here](super::sqrt#sqrt_rem).
639            ///
640            /// # Notes
641            /// For [`u32`] and [`u64`], the square root is computed using Newton's method.
642            #[inline]
643            fn sqrt_rem(self) -> ($u, $u) {
644                sqrt_rem_newton_helper::<$u, $s>(self)
645            }
646        }
647    };
648}
649impl_sqrt_newton!(u32, i32);
650impl_sqrt_newton!(u64, i64);
651
652impl FloorSqrt for u16 {
653    type Output = u16;
654
655    /// Returns the floor of the square root of a [`u16`].
656    ///
657    /// $f(x) = \lfloor\sqrt{x}\rfloor$.
658    ///
659    /// # Worst-case complexity
660    /// Constant time and additional memory.
661    ///
662    /// # Examples
663    /// See [here](super::sqrt#floor_sqrt).
664    ///
665    /// # Notes
666    /// The [`u16`] implementation calls the implementation for [`u32`]s.
667    #[inline]
668    fn floor_sqrt(self) -> u16 {
669        u16::wrapping_from(u32::from(self).floor_sqrt())
670    }
671}
672
673impl CeilingSqrt for u16 {
674    type Output = u16;
675
676    /// Returns the ceiling of the square root of a [`u16`].
677    ///
678    /// $f(x) = \lceil\sqrt{x}\rceil$.
679    ///
680    /// # Worst-case complexity
681    /// Constant time and additional memory.
682    ///
683    /// # Examples
684    /// See [here](super::sqrt#ceiling_sqrt).
685    ///
686    /// # Notes
687    /// The [`u16`] implementation calls the implementation for [`u32`]s.
688    #[inline]
689    fn ceiling_sqrt(self) -> u16 {
690        u16::wrapping_from(u32::from(self).ceiling_sqrt())
691    }
692}
693
694impl CheckedSqrt for u16 {
695    type Output = u16;
696
697    /// Returns the the square root of a [`u16`], or `None` if the integer is not a perfect square.
698    ///
699    /// $$
700    /// f(x) = \\begin{cases}
701    ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
702    ///     \operatorname{None} & \textrm{otherwise}.
703    /// \\end{cases}
704    /// $$
705    ///
706    /// # Worst-case complexity
707    /// Constant time and additional memory.
708    ///
709    /// # Examples
710    /// See [here](super::sqrt#checked_sqrt).
711    ///
712    /// # Notes
713    /// The [`u16`] implementation calls the implementation for [`u32`]s.
714    #[inline]
715    fn checked_sqrt(self) -> Option<u16> {
716        u32::from(self).checked_sqrt().map(u16::wrapping_from)
717    }
718}
719
720impl SqrtRem for u16 {
721    type SqrtOutput = u16;
722    type RemOutput = u16;
723
724    /// Returns the floor of the square root of a [`u16`], and the remainder (the difference between
725    /// the [`u16`] and the square of the floor).
726    ///
727    /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$.
728    ///
729    /// # Worst-case complexity
730    /// Constant time and additional memory.
731    ///
732    /// # Examples
733    /// See [here](super::sqrt#sqrt_rem).
734    ///
735    /// # Notes
736    /// The [`u16`] implementation calls the implementation for [`u32`]s.
737    #[inline]
738    fn sqrt_rem(self) -> (u16, u16) {
739        let (sqrt, rem) = u32::from(self).sqrt_rem();
740        (u16::wrapping_from(sqrt), u16::wrapping_from(rem))
741    }
742}
743
744impl FloorSqrt for usize {
745    type Output = usize;
746
747    /// Returns the floor of the square root of a [`usize`].
748    ///
749    /// $f(x) = \lfloor\sqrt{x}\rfloor$.
750    ///
751    /// # Worst-case complexity
752    /// Constant time and additional memory.
753    ///
754    /// # Examples
755    /// See [here](super::sqrt#floor_sqrt).
756    ///
757    /// # Notes
758    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
759    #[inline]
760    fn floor_sqrt(self) -> usize {
761        if USIZE_IS_U32 {
762            usize::wrapping_from(u32::wrapping_from(self).floor_sqrt())
763        } else {
764            usize::wrapping_from(u64::wrapping_from(self).floor_sqrt())
765        }
766    }
767}
768
769impl CeilingSqrt for usize {
770    type Output = usize;
771
772    /// Returns the ceiling of the square root of a [`usize`].
773    ///
774    /// $f(x) = \lceil\sqrt{x}\rceil$.
775    ///
776    /// # Worst-case complexity
777    /// Constant time and additional memory.
778    ///
779    /// # Examples
780    /// See [here](super::sqrt#ceiling_sqrt).
781    ///
782    /// # Notes
783    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
784    #[inline]
785    fn ceiling_sqrt(self) -> usize {
786        if USIZE_IS_U32 {
787            usize::wrapping_from(u32::wrapping_from(self).ceiling_sqrt())
788        } else {
789            usize::wrapping_from(u64::wrapping_from(self).ceiling_sqrt())
790        }
791    }
792}
793
794impl CheckedSqrt for usize {
795    type Output = usize;
796
797    /// Returns the the square root of a [`usize`], or `None` if the [`usize`] is not a perfect
798    /// square.
799    ///
800    /// $$
801    /// f(x) = \\begin{cases}
802    ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
803    ///     \operatorname{None} & \textrm{otherwise}.
804    /// \\end{cases}
805    /// $$
806    ///
807    /// # Worst-case complexity
808    /// Constant time and additional memory.
809    ///
810    /// # Examples
811    /// See [here](super::sqrt#checked_sqrt).
812    ///
813    /// # Notes
814    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
815    #[inline]
816    fn checked_sqrt(self) -> Option<usize> {
817        if USIZE_IS_U32 {
818            u32::wrapping_from(self)
819                .checked_sqrt()
820                .map(usize::wrapping_from)
821        } else {
822            u64::wrapping_from(self)
823                .checked_sqrt()
824                .map(usize::wrapping_from)
825        }
826    }
827}
828
829impl SqrtRem for usize {
830    type SqrtOutput = usize;
831    type RemOutput = usize;
832
833    /// Returns the floor of the square root of a [`usize`], and the remainder (the difference
834    /// between the [`usize`] and the square of the floor).
835    ///
836    /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$.
837    ///
838    /// # Worst-case complexity
839    /// Constant time and additional memory.
840    ///
841    /// # Examples
842    /// See [here](super::sqrt#sqrt_rem).
843    ///
844    /// # Notes
845    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
846    #[inline]
847    fn sqrt_rem(self) -> (usize, usize) {
848        if USIZE_IS_U32 {
849            let (sqrt, rem) = u32::wrapping_from(self).sqrt_rem();
850            (usize::wrapping_from(sqrt), usize::wrapping_from(rem))
851        } else {
852            let (sqrt, rem) = u64::wrapping_from(self).sqrt_rem();
853            (usize::wrapping_from(sqrt), usize::wrapping_from(rem))
854        }
855    }
856}
857
858// TODO tune
859const U128_SQRT_THRESHOLD: u64 = 125;
860const U128_MAX_SQUARE: u128 = 0xfffffffffffffffe0000000000000001;
861
862impl FloorSqrt for u128 {
863    type Output = u128;
864
865    /// Returns the floor of the square root of a [`u128`].
866    ///
867    /// $f(x) = \lfloor\sqrt{x}\rfloor$.
868    ///
869    /// # Worst-case complexity
870    /// $T(n) = O(n)$
871    ///
872    /// $M(n) = O(1)$
873    ///
874    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
875    ///
876    /// # Examples
877    /// See [here](super::sqrt#floor_sqrt).
878    ///
879    /// # Notes
880    /// For [`u128`], using a floating-point approximation and refining the result works, but the
881    /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large
882    /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following
883    /// fact is used:
884    ///
885    /// If $x$ is nonzero and has $b$ significant bits, then
886    ///
887    /// $2^{b-1} \leq x \leq 2^b-1$,
888    ///
889    /// $2^{b-1} \leq x \leq 2^b$,
890    ///
891    /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$,
892    ///
893    /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$,
894    ///
895    /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq
896    /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is
897    /// weakly increasing,
898    ///
899    /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$.
900    ///
901    /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq
902    /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$.
903    fn floor_sqrt(self) -> u128 {
904        if self.significant_bits() < U128_SQRT_THRESHOLD {
905            floor_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self)
906        } else {
907            floor_sqrt_binary(self)
908        }
909    }
910}
911
912impl CeilingSqrt for u128 {
913    type Output = u128;
914
915    /// Returns the ceiling of the square root of a [`u128`].
916    ///
917    /// $f(x) = \lceil\sqrt{x}\rceil$.
918    ///
919    /// # Worst-case complexity
920    /// $T(n) = O(n)$
921    ///
922    /// $M(n) = O(1)$
923    ///
924    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
925    ///
926    /// # Examples
927    /// See [here](super::sqrt#ceiling_sqrt).
928    ///
929    /// # Notes
930    /// For [`u128`], using a floating-point approximation and refining the result works, but the
931    /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large
932    /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following
933    /// fact is used:
934    ///
935    /// If $x$ is nonzero and has $b$ significant bits, then
936    ///
937    /// $2^{b-1} \leq x \leq 2^b-1$,
938    ///
939    /// $2^{b-1} \leq x \leq 2^b$,
940    ///
941    /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$,
942    ///
943    /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$,
944    ///
945    /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq
946    /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is
947    /// weakly increasing,
948    ///
949    /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$.
950    ///
951    /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq
952    /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$.
953    fn ceiling_sqrt(self) -> u128 {
954        if self.significant_bits() < U128_SQRT_THRESHOLD {
955            ceiling_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self)
956        } else {
957            ceiling_sqrt_binary(self)
958        }
959    }
960}
961
962impl CheckedSqrt for u128 {
963    type Output = u128;
964
965    /// Returns the the square root of a [`u128`], or `None` if the [`u128`] is not a perfect
966    /// square.
967    ///
968    /// $$
969    /// f(x) = \\begin{cases}
970    ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
971    ///     \operatorname{None} & \textrm{otherwise}.
972    /// \\end{cases}
973    /// $$
974    ///
975    /// # Worst-case complexity
976    /// $T(n) = O(n)$
977    ///
978    /// $M(n) = O(1)$
979    ///
980    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
981    ///
982    /// # Examples
983    /// See [here](super::sqrt#checked_sqrt).
984    ///
985    /// # Notes
986    /// For [`u128`], using a floating-point approximation and refining the result works, but the
987    /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large
988    /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following
989    /// fact is used:
990    ///
991    /// If $x$ is nonzero and has $b$ significant bits, then
992    ///
993    /// $2^{b-1} \leq x \leq 2^b-1$,
994    ///
995    /// $2^{b-1} \leq x \leq 2^b$,
996    ///
997    /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$,
998    ///
999    /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$,
1000    ///
1001    /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq
1002    /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is
1003    /// weakly increasing,
1004    ///
1005    /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$.
1006    ///
1007    /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq
1008    /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$.
1009    fn checked_sqrt(self) -> Option<u128> {
1010        if self.significant_bits() < U128_SQRT_THRESHOLD {
1011            checked_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self)
1012        } else {
1013            checked_sqrt_binary(self)
1014        }
1015    }
1016}
1017
1018impl SqrtRem for u128 {
1019    type SqrtOutput = u128;
1020    type RemOutput = u128;
1021
1022    /// Returns the floor of the square root of a [`u128`], and the remainder (the difference
1023    /// between the [`u128`] and the square of the floor).
1024    ///
1025    /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$.
1026    ///
1027    /// # Worst-case complexity
1028    /// $T(n) = O(n)$
1029    ///
1030    /// $M(n) = O(1)$
1031    ///
1032    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1033    ///
1034    /// # Examples
1035    /// See [here](super::sqrt#sqrt_rem).
1036    ///
1037    /// # Notes
1038    /// For [`u128`], using a floating-point approximation and refining the result works, but the
1039    /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large
1040    /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following
1041    /// fact is used:
1042    ///
1043    /// If $x$ is nonzero and has $b$ significant bits, then
1044    ///
1045    /// $2^{b-1} \leq x \leq 2^b-1$,
1046    ///
1047    /// $2^{b-1} \leq x \leq 2^b$,
1048    ///
1049    /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$,
1050    ///
1051    /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$,
1052    ///
1053    /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq
1054    /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is
1055    /// weakly increasing,
1056    ///
1057    /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$.
1058    ///
1059    /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq
1060    /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$.
1061    fn sqrt_rem(self) -> (u128, u128) {
1062        if self.significant_bits() < U128_SQRT_THRESHOLD {
1063            sqrt_rem_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self)
1064        } else {
1065            sqrt_rem_binary(self)
1066        }
1067    }
1068}
1069
1070macro_rules! impl_sqrt_signed {
1071    ($u: ident, $s: ident) => {
1072        impl FloorSqrt for $s {
1073            type Output = $s;
1074
1075            /// Returns the floor of the square root of an integer.
1076            ///
1077            /// $f(x) = \lfloor\sqrt{x}\rfloor$.
1078            ///
1079            /// # Worst-case complexity
1080            /// Constant time and additional memory.
1081            ///
1082            /// # Panics
1083            /// Panics if `self` is negative.
1084            ///
1085            /// # Examples
1086            /// See [here](super::sqrt#floor_sqrt).
1087            #[inline]
1088            fn floor_sqrt(self) -> Self {
1089                if self >= 0 {
1090                    $s::wrapping_from(self.unsigned_abs().floor_sqrt())
1091                } else {
1092                    panic!("Cannot take square root of {}", self)
1093                }
1094            }
1095        }
1096
1097        impl CeilingSqrt for $s {
1098            type Output = $s;
1099
1100            /// Returns the ceiling of the square root of an integer.
1101            ///
1102            /// $f(x) = \lceil\sqrt{x}\rceil$.
1103            ///
1104            /// # Worst-case complexity
1105            /// Constant time and additional memory.
1106            ///
1107            /// # Panics
1108            /// Panics if `self` is negative.
1109            ///
1110            /// # Examples
1111            /// See [here](super::sqrt#ceiling_sqrt).
1112            #[inline]
1113            fn ceiling_sqrt(self) -> $s {
1114                if self >= 0 {
1115                    $s::wrapping_from(self.unsigned_abs().ceiling_sqrt())
1116                } else {
1117                    panic!("Cannot take square root of {}", self)
1118                }
1119            }
1120        }
1121
1122        impl CheckedSqrt for $s {
1123            type Output = $s;
1124
1125            /// Returns the the square root of an integer, or `None` if the integer is not a perfect
1126            /// square.
1127            ///
1128            /// $$
1129            /// f(x) = \\begin{cases}
1130            ///     \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\
1131            ///     \operatorname{None} & \textrm{otherwise}.
1132            /// \\end{cases}
1133            /// $$
1134            ///
1135            /// # Worst-case complexity
1136            /// Constant time and additional memory.
1137            ///
1138            /// # Panics
1139            /// Panics if `self` is negative.
1140            ///
1141            /// # Examples
1142            /// See [here](super::sqrt#checked_sqrt).
1143            #[inline]
1144            fn checked_sqrt(self) -> Option<$s> {
1145                if self >= 0 {
1146                    self.unsigned_abs().checked_sqrt().map($s::wrapping_from)
1147                } else {
1148                    panic!("Cannot take square root of {}", self)
1149                }
1150            }
1151        }
1152    };
1153}
1154apply_to_unsigned_signed_pairs!(impl_sqrt_signed);
1155
1156macro_rules! impl_sqrt_assign_rem_unsigned {
1157    ($t: ident) => {
1158        impl SqrtAssignRem for $t {
1159            type RemOutput = $t;
1160
1161            /// Replaces an integer with the floor of its square root, and returns the remainder
1162            /// (the difference between the original integer and the square of the floor).
1163            ///
1164            /// $f(x) = x - \lfloor\sqrt{x}\rfloor^2$,
1165            ///
1166            /// $x \gets \lfloor\sqrt{x}\rfloor$.
1167            ///
1168            /// # Worst-case complexity
1169            /// Constant time and additional memory.
1170            ///
1171            /// # Examples
1172            /// See [here](super::sqrt#sqrt_assign_rem).
1173            #[inline]
1174            fn sqrt_assign_rem(&mut self) -> $t {
1175                let rem;
1176                (*self, rem) = self.sqrt_rem();
1177                rem
1178            }
1179        }
1180    };
1181}
1182apply_to_unsigneds!(impl_sqrt_assign_rem_unsigned);
1183
1184macro_rules! impl_sqrt_assign {
1185    ($t: ident) => {
1186        impl FloorSqrtAssign for $t {
1187            /// Replaces an integer with the floor of its square root.
1188            ///
1189            /// $x \gets \lfloor\sqrt{x}\rfloor$.
1190            ///
1191            /// # Worst-case complexity
1192            /// Constant time and additional memory.
1193            ///
1194            /// # Panics
1195            /// Panics if `self` is negative.
1196            ///
1197            /// # Examples
1198            /// See [here](super::sqrt#floor_sqrt_assign).
1199            #[inline]
1200            fn floor_sqrt_assign(&mut self) {
1201                *self = self.floor_sqrt();
1202            }
1203        }
1204
1205        impl CeilingSqrtAssign for $t {
1206            /// Replaces an integer with the ceiling of its square root.
1207            ///
1208            /// $x \gets \lceil\sqrt{x}\rceil$.
1209            ///
1210            /// # Worst-case complexity
1211            /// Constant time and additional memory.
1212            ///
1213            /// # Panics
1214            /// Panics if `self` is negative.
1215            ///
1216            /// # Examples
1217            /// See [here](super::sqrt#ceiling_sqrt_assign).
1218            #[inline]
1219            fn ceiling_sqrt_assign(&mut self) {
1220                *self = self.ceiling_sqrt();
1221            }
1222        }
1223    };
1224}
1225apply_to_primitive_ints!(impl_sqrt_assign);
1226
1227macro_rules! impl_sqrt_primitive_float {
1228    ($f:ident) => {
1229        impl Sqrt for $f {
1230            type Output = Self;
1231
1232            #[inline]
1233            fn sqrt(self) -> $f {
1234                libm::Libm::<$f>::sqrt(self)
1235            }
1236        }
1237
1238        // TODO move to better location
1239        impl Ln for $f {
1240            type Output = Self;
1241
1242            #[inline]
1243            fn ln(self) -> $f {
1244                libm::Libm::<$f>::log(self)
1245            }
1246        }
1247
1248        impl SqrtAssign for $f {
1249            /// Replaces a number with its square root.
1250            ///
1251            /// $x \gets \sqrt x$.
1252            ///
1253            /// # Worst-case complexity
1254            /// Constant time and additional memory.
1255            ///
1256            /// # Examples
1257            /// See [here](super::sqrt#sqrt_assign).
1258            #[inline]
1259            fn sqrt_assign(&mut self) {
1260                *self = self.sqrt();
1261            }
1262        }
1263    };
1264}
1265apply_to_primitive_floats!(impl_sqrt_primitive_float);