What is an idiomatic way of calculating the power ...
# getting-started
n
What is an idiomatic way of calculating the power of two for integers?
j
You mean 2^n ? You can shift to the left I guess, using
1 shl n
d
If you care about the readers of your code please don't use bit shifts if you don't have to 😄 I think good old java.lang.Math.pow is a good bet. Or you can build an an extension function which uses the already existing https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/pow.html#kotlin.math$pow(kotlin.Double,%20kotlin.Double) (I wonder why they did not build an extension for Int)
j
If you make an extension function for 2^n, you may as well use the bit shift inside :D but if you don't I would argue the extra conversions between doubles and ints might actually make it on par in terms of readability
I'd rather read
1 shl n // 2^n
than
Math.pow(2.0, n.toDouble()).toInt()
4
s
better add an argument range check
Copy code
fun twoPow(exponent: Int): Int {
  require(exponent in 0..32) {"exponent must be in 0-31 but was $exponent"}
  return 1 shl n // 2^n
}
val x = twoPow(5)
is hopefully even easier to read. I didn't make it an extension function because i wanted to retain the order of 2 and 5.
n
Math.pow()
can't guarantee the precision of what I need for bitwise operations.
shl
does not look idiomatic either, because it is hard to read. I would say
twoPow(x)
is winner here, however, it does not look idiomatic because it is not a part of stdlib, but maybe should
I wonder why they did not build an extension for Int
I guess it is because of precision. Double does not need that much of it.
m
for any arbritary int, I'd rather use
Copy code
fun Int.pow(power: Int) = toBigInteger().pow(power)
powers can quite easily grow outside of the scope of an Int, so you have to decide what to do if your int gets out of range for its size. If you feel like you don't care, you can just do the .toInt() as part of it again.
j
@neworldlt the short answer is that there isn't really any idiomatic way because there isn't anything in the stdlib for this use case at the moment (at least to my knowledge). So now you have to pick your non-idiomatic poison 🙂 Most options suggested here seem valid to me at least in some contexts. • If you're dealing with powers of 2 exclusively in this piece of code, I would go for the bit shift. It's short enough so it's easy to lookup for beginners that don't understand it, and a quick
// 2^n
comment is a very short and clear way to explain the intent of it. But if it's not enough you can also extract it to a function like @Stephan Schroeder suggested. Also, incidentally (if it matters) I believe its performance will outweigh any other options in this case. • If the base 2 was just incidental here and you're in fact using other bases in the same area of code, a custom extension for
Int.pow(Int)
as @Michael de Kaste suggested would be my choice. The way you implement it is up to you (going through
Double
or
BigInteger
) but likely
BigInteger
will be safer regarding overflows
👍 1