From 1e02bdb415e4738e8908d9051f162b06733dc662 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Mon, 7 Sep 2020 20:44:32 -0700 Subject: [PATCH] Use leading_zeros to compute initial bit This increases performance on processors with lzcnt instructions. Signed-off-by: Joe Richey --- src/lib.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bd65c40..9d93c55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,17 +46,18 @@ pub trait IntegerSquareRoot { #[inline(always)] fn integer_sqrt_impl(mut n: T) -> Option { - // Hopefully this will be stripped for unsigned numbers (impossible condition) - if n < T::zero() { - return None; + use core::cmp::Ordering; + match n.cmp(&T::zero()) { + // Hopefully this will be stripped for unsigned numbers (impossible condition) + Ordering::Less => return None, + Ordering::Equal => return Some(T::zero()), + _ => {} } // Compute bit, the largest power of 4 <= n - use core::mem::size_of; - let mut bit = T::one().unsigned_shl(size_of::() as u32 * 8 - 2); - while bit > n { - bit = bit.unsigned_shr(2); - } + let max_shift: u32 = T::zero().leading_zeros() - 1; + let shift: u32 = (max_shift - n.leading_zeros()) & !1; + let mut bit = T::one().unsigned_shl(shift); // Algorithm based on the implementation in: // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)