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