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 } ;
@@ -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 = $signedness $Int,
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 $ signedness $Int) ;
826
+ nonzero_integer_signedness_dependent_impls!( $signedness $Int) ;
827
827
} ;
828
828
829
829
( Self = $Ty: ident, Primitive = unsigned $Int: 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 square root of an integer >= 1 is always >= 1.
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
) => {
0 commit comments