Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3e8676c

Browse files
committed
isqrt: initial implementation
1 parent 03c199a commit 3e8676c

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

library/core/src/num/int_macros.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,45 @@ macro_rules! int_impl {
898898
acc.checked_mul(base)
899899
}
900900

901+
/// Returns the square root of the number, rounded down.
902+
///
903+
/// Returns `None` if `self` is negative.
904+
///
905+
/// # Examples
906+
///
907+
/// Basic usage:
908+
/// ```
909+
#[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")]
910+
/// ```
911+
#[stable(feature = "isqrt", since = "1.73.0")]
912+
#[rustc_const_stable(feature = "isqrt", since = "1.73.0")]
913+
#[must_use = "this returns the result of the operation, \
914+
without modifying the original"]
915+
#[inline]
916+
pub const fn checked_isqrt(self) -> Option<Self> {
917+
if self < 0 {
918+
return None;
919+
} else if self < 2 {
920+
return Some(self);
921+
}
922+
923+
let mut x: Self = self;
924+
let mut c: Self = 0;
925+
let mut d: Self = 1 << (self.ilog2() & !1);
926+
927+
while (d != 0) {
928+
if x >= c + d {
929+
x -= c + d;
930+
c = (c >> 1) + d;
931+
} else {
932+
c >>= 1;
933+
}
934+
d >>= 2;
935+
}
936+
937+
return Some(c);
938+
}
939+
901940
/// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
902941
/// bounds instead of overflowing.
903942
///
@@ -2061,6 +2100,47 @@ macro_rules! int_impl {
20612100
acc * base
20622101
}
20632102

2103+
/// Returns the square root of the number, rounded down.
2104+
///
2105+
/// # Panics
2106+
///
2107+
/// This function will panic if `self` is negative.
2108+
///
2109+
/// # Examples
2110+
///
2111+
/// Basic usage:
2112+
/// ```
2113+
#[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
2114+
/// ```
2115+
#[stable(feature = "isqrt", since = "1.73.0")]
2116+
#[rustc_const_stable(feature = "isqrt", since = "1.73.0")]
2117+
#[must_use = "this returns the result of the operation, \
2118+
without modifying the original"]
2119+
#[inline]
2120+
pub const fn isqrt(self) -> Self {
2121+
if self < 0 {
2122+
panic!("argument of integer square root must be non-negative")
2123+
} else if self < 2 {
2124+
return self;
2125+
}
2126+
2127+
let mut x: Self = self;
2128+
let mut c: Self = 0;
2129+
let mut d: Self = 1 << (self.ilog2() & !1);
2130+
2131+
while (d != 0) {
2132+
if x >= c + d {
2133+
x -= c + d;
2134+
c = (c >> 1) + d;
2135+
} else {
2136+
c >>= 1;
2137+
}
2138+
d >>= 2;
2139+
}
2140+
2141+
return c;
2142+
}
2143+
20642144
/// Calculates the quotient of Euclidean division of `self` by `rhs`.
20652145
///
20662146
/// This computes the integer `q` such that `self = q * rhs + r`, with

library/core/src/num/uint_macros.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,41 @@ macro_rules! uint_impl {
19791979
acc * base
19801980
}
19811981

1982+
/// Returns the square root of the number, rounded down.
1983+
///
1984+
/// # Examples
1985+
///
1986+
/// Basic usage:
1987+
/// ```
1988+
#[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
1989+
/// ```
1990+
#[stable(feature = "isqrt", since = "1.73.0")]
1991+
#[rustc_const_stable(feature = "isqrt", since = "1.73.0")]
1992+
#[must_use = "this returns the result of the operation, \
1993+
without modifying the original"]
1994+
#[inline]
1995+
pub const fn isqrt(self) -> Self {
1996+
if self < 2 {
1997+
return self;
1998+
}
1999+
2000+
let mut x: Self = self;
2001+
let mut c: Self = 0;
2002+
let mut d: Self = 1 << (self.ilog2() & !1);
2003+
2004+
while (d != 0) {
2005+
if x >= c + d {
2006+
x -= c + d;
2007+
c = (c >> 1) + d;
2008+
} else {
2009+
c >>= 1;
2010+
}
2011+
d >>= 2;
2012+
}
2013+
2014+
return c;
2015+
}
2016+
19822017
/// Performs Euclidean division.
19832018
///
19842019
/// Since, for the positive integers, all common

0 commit comments

Comments
 (0)