about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFederico Stra <stra.federico@gmail.com>2023-09-26 15:44:28 +0200
committerFederico Stra <stra.federico@gmail.com>2023-09-26 15:46:14 +0200
commit68f0b475c76de88fb5cb37c8cd0163703354415a (patch)
tree7ca96963ec6fcaeb75a75a2f4dac03313cff1d01
parent1b34f1c6b2b407c286f0e0bac084114c7475c61e (diff)
downloadrust-68f0b475c76de88fb5cb37c8cd0163703354415a.tar.gz
rust-68f0b475c76de88fb5cb37c8cd0163703354415a.zip
isqrt: remove duplication by delegating to unsigned integers
-rw-r--r--library/core/src/num/int_macros.rs50
-rw-r--r--library/core/src/num/uint_macros.rs2
2 files changed, 12 insertions, 40 deletions
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 66bd8001353..8bc82b5fc88 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -915,26 +915,10 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_isqrt(self) -> Option<Self> {
             if self < 0 {
-                return None;
-            } else if self < 2 {
-                return Some(self);
-            }
-
-            let mut x: Self = self;
-            let mut c: Self = 0;
-            let mut d: Self = 1 << (self.ilog2() & !1);
-
-            while (d != 0) {
-                if x >= c + d {
-                    x -= c + d;
-                    c = (c >> 1) + d;
-                } else {
-                    c >>= 1;
-                }
-                d >>= 2;
+                None
+            } else {
+                Some((self as $UnsignedT).isqrt() as Self)
             }
-
-            return Some(c);
         }
 
         /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
@@ -2118,27 +2102,15 @@ macro_rules! int_impl {
                       without modifying the original"]
         #[inline]
         pub const fn isqrt(self) -> Self {
-            if self < 0 {
-                panic!("argument of integer square root must be non-negative")
-            } else if self < 2 {
-                return self;
-            }
-
-            let mut x: Self = self;
-            let mut c: Self = 0;
-            let mut d: Self = 1 << (self.ilog2() & !1);
-
-            while (d != 0) {
-                if x >= c + d {
-                    x -= c + d;
-                    c = (c >> 1) + d;
-                } else {
-                    c >>= 1;
-                }
-                d >>= 2;
+            // I would like to implement it as
+            // ```
+            // self.checked_isqrt().expect("argument of integer square root must be non-negative")
+            // ```
+            // but `expect` is not yet stable as a `const fn`.
+            match self.checked_isqrt() {
+                Some(sqrt) => sqrt,
+                None => panic!("argument of integer square root must be non-negative"),
             }
-
-            return c;
         }
 
         /// Calculates the quotient of Euclidean division of `self` by `rhs`.
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 4c093ab8220..f8005694ceb 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2011,7 +2011,7 @@ macro_rules! uint_impl {
                 d >>= 2;
             }
 
-            return c;
+            c
         }
 
         /// Performs Euclidean division.