@@ -335,6 +335,11 @@ function invmod(n::T) where {T<:BitInteger}
335335end
336336
337337# ^ for any x supporting *
338+ function to_power_type (x:: Number )
339+ T = promote_type (typeof (x), typeof (x* x))
340+ convert (T, x)
341+ end
342+ to_power_type (x) = oftype (x* x, x)
338343@noinline throw_domerr_powbysq (:: Any , p) = throw (DomainError (p, LazyString (
339344 " Cannot raise an integer x to a negative power " , p, " ." ,
340345 " \n Convert input to float." )))
@@ -350,23 +355,12 @@ end
350355 " or write float(x)^" , p, " or Rational.(x)^" , p, " ." )))
351356# The * keyword supports `*=checked_mul` for `checked_pow`
352357@assume_effects :terminates_locally function power_by_squaring (x_, p:: Integer ; mul= * )
353- x_squared_ = x_ * x_
354- x_squared_type = typeof (x_squared_)
355- T = if x_ isa Number
356- promote_type (typeof (x_), x_squared_type)
357- else
358- x_squared_type
359- end
360- x = convert (T, x_)
361- square_is_useful = mul === *
358+ x = to_power_type (x_)
362359 if p == 1
363360 return copy (x)
364361 elseif p == 0
365362 return one (x)
366363 elseif p == 2
367- if square_is_useful # avoid performing the same multiplication a second time when possible
368- return convert (T, x_squared_)
369- end
370364 return mul (x, x)
371365 elseif p < 0
372366 isone (x) && return copy (x)
375369 end
376370 t = trailing_zeros (p) + 1
377371 p >>= t
378- if square_is_useful # avoid performing the same multiplication a second time when possible
379- if (t -= 1 ) > 0
380- x = convert (T, x_squared_)
381- end
382- end
383372 while (t -= 1 ) > 0
384373 x = mul (x, x)
385374 end
0 commit comments