add NonZero<uN>::isqrt
· model-checking/verify-rust-std@9348998 (original) (raw)
`@@ -3,6 +3,7 @@
`
3
3
`use crate::cmp::Ordering;
`
4
4
`use crate::fmt;
`
5
5
`use crate::hash::{Hash, Hasher};
`
``
6
`+
use crate::hint;
`
6
7
`use crate::intrinsics;
`
7
8
`use crate:📑:{Freeze, StructuralPartialEq};
`
8
9
`use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
`
`@@ -604,7 +605,6 @@ macro_rules! nonzero_integer {
`
604
605
`}
`
605
606
``
606
607
` nonzero_integer_signedness_dependent_methods! {
`
607
``
`-
Self = $Ty,
`
608
608
`Primitive = signednesssignedness signednessInt,
`
609
609
`UnsignedPrimitive = $Uint,
`
610
610
`}
`
`@@ -823,7 +823,7 @@ macro_rules! nonzero_integer {
`
823
823
`}
`
824
824
`}
`
825
825
``
826
``
`-
nonzero_integer_signedness_dependent_impls!($Ty signednesssignedness signednessInt);
`
``
826
`+
nonzero_integer_signedness_dependent_impls!($signedness $Int);
`
827
827
`};
`
828
828
``
829
829
`(Self = Ty:ident,Primitive=unsignedTy:ident, Primitive = unsigned Ty:ident,Primitive=unsignedInt:ident $(,)?) => {
`
`@@ -849,7 +849,7 @@ macro_rules! nonzero_integer {
`
849
849
``
850
850
`macro_rules! nonzero_integer_signedness_dependent_impls {
`
851
851
`// Impls for unsigned nonzero types only.
`
852
``
`-
($Ty:ident unsigned $Int:ty) => {
`
``
852
`+
(unsigned $Int:ty) => {
`
853
853
` #[stable(feature = "nonzero_div", since = "1.51.0")]
`
854
854
`impl Div<NonZero<$Int>> for $Int {
`
855
855
`type Output = $Int;
`
`@@ -897,7 +897,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
`
897
897
`}
`
898
898
`};
`
899
899
`// Impls for signed nonzero types only.
`
900
``
`-
($Ty:ident signed $Int:ty) => {
`
``
900
`+
(signed $Int:ty) => {
`
901
901
` #[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
`
902
902
`impl Neg for NonZero<$Int> {
`
903
903
`type Output = Self;
`
`@@ -918,7 +918,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
`
918
918
`macro_rules! nonzero_integer_signedness_dependent_methods {
`
919
919
`// Associated items for unsigned nonzero types only.
`
920
920
`(
`
921
``
`-
Self = $Ty:ident,
`
922
921
`Primitive = unsigned $Int:ident,
`
923
922
`UnsignedPrimitive = $Uint:ty,
`
924
923
`) => {
`
`@@ -1224,11 +1223,60 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
`
1224
1223
``
1225
1224
` intrinsics::ctpop(self.get()) < 2
`
1226
1225
`}
`
``
1226
+
``
1227
`+
/// Returns the square root of the number, rounded down.
`
``
1228
`+
///
`
``
1229
`+
/// # Examples
`
``
1230
`+
///
`
``
1231
`+
/// Basic usage:
`
``
1232
/// ```
``
1233
`+
/// #![feature(isqrt)]
`
``
1234
`+
/// # use std::num::NonZero;
`
``
1235
`+
/// #
`
``
1236
`+
/// # fn main() { test().unwrap(); }
`
``
1237
`+
/// # fn test() -> Option<()> {
`
``
1238
`+
#[doc = concat!("let ten = NonZero::new(10", stringify!($Int), ")?;")]
`
``
1239
`+
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
`
``
1240
`+
///
`
``
1241
`+
/// assert_eq!(ten.isqrt(), three);
`
``
1242
`+
/// # Some(())
`
``
1243
`+
/// # }
`
``
1244
`+
#[unstable(feature = "isqrt", issue = "116226")]
`
``
1245
`+
#[rustc_const_unstable(feature = "isqrt", issue = "116226")]
`
``
1246
`+
#[must_use = "this returns the result of the operation, \
`
``
1247
`+
without modifying the original"]
`
``
1248
`+
#[inline]
`
``
1249
`+
pub const fn isqrt(self) -> Self {
`
``
1250
`+
// The algorithm is based on the one presented in
`
``
1251
`+
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
`
``
1252
`+
// which cites as source the following C code:
`
``
1253
`+
// https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c.
`
``
1254
+
``
1255
`+
let mut op = self.get();
`
``
1256
`+
let mut res = 0;
`
``
1257
`+
let mut one = 1 << (self.ilog2() & !1);
`
``
1258
+
``
1259
`+
while one != 0 {
`
``
1260
`+
if op >= res + one {
`
``
1261
`+
op -= res + one;
`
``
1262
`+
res = (res >> 1) + one;
`
``
1263
`+
} else {
`
``
1264
`+
res >>= 1;
`
``
1265
`+
}
`
``
1266
`+
one >>= 2;
`
``
1267
`+
}
`
``
1268
+
``
1269
`+
// SAFETY: The result fits in an integer with half as many bits.
`
``
1270
`+
// Inform the optimizer about it.
`
``
1271
`+
unsafe { hint::assert_unchecked(res < 1 << (Self::BITS / 2)) };
`
``
1272
+
``
1273
`+
// SAFETY: The result is positive.
`
``
1274
`+
unsafe { Self::new_unchecked(res) }
`
``
1275
`+
}
`
1227
1276
`};
`
1228
1277
``
1229
1278
`// Associated items for signed nonzero types only.
`
1230
1279
`(
`
1231
``
`-
Self = $Ty:ident,
`
1232
1280
`Primitive = signed $Int:ident,
`
1233
1281
`UnsignedPrimitive = $Uint:ty,
`
1234
1282
`) => {
`