To preserve the actual printed function, including its handling of nonpositive exponents and wrapping
Int bases, use a tail-recursive accumulator with the same multiplication order:def anotherfuncRec(x: Int, n: Long): Double = {
require(x > 0)
@scala.annotation.tailrec
def loop(y: Int, i: Long, result: Double): Double = {
if (i <= 0) result
else {
val nextResult = if (i % 2 == 1) result * y else result
loop(y * y, i / 2, nextResult)
}
}
loop(x, n, 1.0)
}Each recursive call corresponds to one source iteration and carries exactly its next program state. Hence it reproduces the printed numerical behavior, rather than silently repairing it. For positive
n, both routines use steps; for nonpositive n, both take constant time. The recursive call is in tail position, so Scala's tail-call optimization avoids a growing call stack; the annotation asks the compiler to check that condition.If the intended exact power is required instead, change the base and accumulator parameters of this same recurrence to
BigInt and require n >= 0, as in part (d). Its mathematical loop invariant becomes a recursion invariant, with the same logarithmic number of multiplication steps. Articles by others on the same topic
There are currently no matching articles.