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);