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

`) => {

`