The logarithm method needs more care, because the logarithm function has a small amount of inaccuracy due to the use of floating-point approximations. For example 310 = 59049, but:
log(59049, 3)
===> 9.999999999999998
Whether you can compensate for this (by checking to see if the answer is "close enough" to the nearest integer) depends on the range of your x and y. If y is less than 232, then I think the closest the logarithm can proportionately get to an integer (without the true answer being an integer) is:
1 - log(4294967295, 65536) / 2
===> 1.049693665322593e-11
so pick an epsilon smaller than this and you can use the logarithm method with confidence:
n = log(y, x);
e = round(n);
if (abs(1 - n / e) < epsilon) {
/* y == x to the power of e */
} else {
/* y not a power of x */
}
If the allowable range for y is bigger, then you'll have to find the appropriate value for epsilon. But beware: for large enough y, there might be no suitable epsilon in double-precision floating-point. For example, if y can be as large as 248 − 1 then that's the case, because
log(281474976710655, 16777216)
===> 2.0 exactly
So for large enough y, you can't rely on the logarithm: you'll need to explicitly perform the exponentiation afterwards as a check.