def test_zero_count(self): lz = njit(lambda x: leading_zeros(x)) tz = njit(lambda x: trailing_zeros(x)) evens = [2, 42, 126, 128] for T in types.unsigned_domain: self.assertTrue(tz(T(0)) == lz(T(0)) == T.bitwidth) for i in range(T.bitwidth): val = T(2**i) self.assertEqual(lz(val) + tz(val) + 1, T.bitwidth) for n in evens: self.assertGreater(tz(T(n)), 0) self.assertEqual(tz(T(n + 1)), 0) for T in types.signed_domain: self.assertTrue(tz(T(0)) == lz(T(0)) == T.bitwidth) for i in range(T.bitwidth - 1): val = T(2**i) self.assertEqual(lz(val) + tz(val) + 1, T.bitwidth) self.assertEqual(lz(-val), 0) self.assertEqual(tz(val), tz(-val)) for n in evens: self.assertGreater(tz(T(n)), 0) self.assertEqual(tz(T(n + 1)), 0)
def gcd(a, b): """ Stein's algorithm, heavily cribbed from Julia implementation. """ T = type(a) if a == 0: return abs(b) if b == 0: return abs(a) za = trailing_zeros(a) zb = trailing_zeros(b) k = min(za, zb) # Uses np.*_shift instead of operators due to return types u = _unsigned(abs(np.right_shift(a, za))) v = _unsigned(abs(np.right_shift(b, zb))) while u != v: if u > v: u, v = v, u v -= u v = np.right_shift(v, trailing_zeros(v)) r = np.left_shift(T(u), k) return r