def exponent(self, p, q, digits): if not self.integer_check(q) or p == 1: return base = math.log2( max(p.rational_part.numerator, p.rational_part.denominator)) exp = Expression.power(p, q), Expression.power(p, Expression.negate(q)) q_max = q.rational_part.numerator while base * q_max > self.MAX_DIGITS << p.quadratic_power: if q_max & 1 == 0: q_max >>= 1 exp = Expression.sqrt(exp[0]), Expression.sqrt(exp[1]) else: return q_min = q_max while q_min & 1 == 0: q_min >>= 1 exp = Expression.sqrt(exp[0]), Expression.sqrt(exp[1]) q = q_min x = p**q while q <= q_max: if not self.range_check(x): break self.check(x, digits, exp[0], need_sqrt=q == q_min) self.check(Quadratic.inverse(x), digits, exp[1], need_sqrt=q == q_min) q <<= 1 x = Quadratic.square(x) if q <= q_max: exp = exp[0].args[0], exp[1].args[0]
def exponent(self, p, q, digits): if q.denominator != 1 or p == 1: return p_digits = math.log2(max(p.numerator, p.denominator)) q_int = q.numerator exp = Expression.power(p, q), Expression.power(p, Expression.negate(q)) while p_digits * q_int > self.MAX_DIGITS: if q_int & 1 == 0: q_int >>= 1 exp = Expression.sqrt(exp[0]), Expression.sqrt(exp[1]) else: return x = p**q_int self.check(x, digits, exp[0]) self.check(x**-1, digits, exp[1])