Stabilization report
API summary
const fn concerns
If a better implementation comes along that can't be const fn, const_eval_select can be used to combine the better implementation with the current implementation to maintain const fn.
Experience report
These projects use the isqrt feature (note that only five pages of results are allowed, so there may be more uses):
Standard libraries of programming languages
The following languages have an integer square root function in the standard library: Chapel, Common Lisp, Crystal, Julia, Maple, Python 3, Racket, Ruby, SageMath, Scheme, and Tcl.
Rust crates
integer-sqrt (6.3 million downloads of all versions; GitHub search)
num-bigint (133 million downloads of all versions)
rug (590 thousand downloads of all versions)
Other languages
GMP library
Implementation history
Performance
The current implementation is based on a lookup table for 8-bit integers and "unrolled" recursive Karatsuba square root for larger types. The performance is decent, but it can be beaten with f32::sqrt and f64::sqrt for 16-bit through 64-bit integers (64 bit needs a slight adjustment to correct for imprecision). Even 128-bit integers could be sped up by using Karatsuba square root combined with the 64-bit floating point-based algorithm.
It isn't done that way because:
- Rust has no runtime detection of fast floating point hardware square root instructions (software-based floating point square roots are likely to be slower than the current implementation).
- Rust has no way to allow the Linux kernel and similar projects to forbid floating point arithmetic and to communicate that to
core library code via a cfg setting or similar.
Ignoring floating point implementations, there are also faster algorithms that use only integer operations (for example the GMP library has faster implementations). I'm not a lawyer, but I believe that porting those to Rust would be considered a derivative work, and thus require adherence to the original code's license. Since the Rust standard library appears to be dual licensed under Apache 2.0 and MIT and since GMP is licensed under both LGPL 2 and LGPL 3, we'd have to complicate our licensing situation to port the GMP code.
Is there anything else that needs to be taken care of before the isqrt feature is stabilized?
Stabilization report
API summary
i*:n.isqrt()(panics ifnis negative) andn.checked_isqrt()(Noneifnis negative) (accepted by @dtolnay without ACP)u*:n.isqrt()(accepted by @dtolnay without ACP)NonZeroU*:n.isqrt()(ACP accepted)const fnconst fnconcernsIf a better implementation comes along that can't be
const fn,const_eval_selectcan be used to combine the better implementation with the current implementation to maintainconst fn.Experience report
These projects use the
isqrtfeature (note that only five pages of results are allowed, so there may be more uses):#![feature(isqrt)].isqrt().checked_isqrt()(right now, there appear to be very few uses that aren'trust-lang/rustforks)Standard libraries of programming languages
The following languages have an integer square root function in the standard library: Chapel, Common Lisp, Crystal, Julia, Maple, Python 3, Racket, Ruby, SageMath, Scheme, and Tcl.
Rust crates
integer-sqrt(6.3 million downloads of all versions; GitHub search)num-bigint(133 million downloads of all versions)rug(590 thousand downloads of all versions)Other languages
GMP library
Implementation history
isqrtandchecked_isqrtmethods added to primitive types during 1.74 nightly: Add "integer square root" method to integer primitive types rust-lang/rust#116176isqrtmethod on unsignedNonZerotypes during 1.80 nightly: ACP:isqrtforNonZero<uN>rust-lang/libs-team#391isqrtmethod added to unsignedNonZerotypes during 1.81 nightly: AddisqrttoNonZero<uN>rust-lang/rust#126199checked_isqrtandisqrtmethods rust-lang/rust#128166Performance
The current implementation is based on a lookup table for 8-bit integers and "unrolled" recursive Karatsuba square root for larger types. The performance is decent, but it can be beaten with
f32::sqrtandf64::sqrtfor 16-bit through 64-bit integers (64 bit needs a slight adjustment to correct for imprecision). Even 128-bit integers could be sped up by using Karatsuba square root combined with the 64-bit floating point-based algorithm.It isn't done that way because:
corelibrary code via acfgsetting or similar.Ignoring floating point implementations, there are also faster algorithms that use only integer operations (for example the GMP library has faster implementations). I'm not a lawyer, but I believe that porting those to Rust would be considered a derivative work, and thus require adherence to the original code's license. Since the Rust standard library appears to be dual licensed under Apache 2.0 and MIT and since GMP is licensed under both LGPL 2 and LGPL 3, we'd have to complicate our licensing situation to port the GMP code.
Is there anything else that needs to be taken care of before the
isqrtfeature is stabilized?