什么是Kotlin指数运算符

时间:2018-05-10 10:08:57

标签: kotlin

Kotlin中的指数运算符是什么。我以为它会**,但它似乎在我的代码中引发错误。

when (pendingOperation) {
    "=" -> operand1 = value
    "÷" -> operand1 = if (value == 0.0) {
        Double.NaN // handle attempt to divide by zero
    } else {
        operand1!! / value
    }
    "x" -> operand1 = operand1!! * value
    "−" -> operand1 = operand1!! - value
    "+" -> operand1 = operand1!! + value
    "a^b" -> operand1 = operand1!! ** value

5 个答案:

答案 0 :(得分:17)

Kotlin和Java一样,没有指数运算符。 Java有Math.pow,你可以和Kotlin一起使用,但是Kotlin也有Float和Double的扩展函数,你可以使用它。

如果您需要使用带有Ints或Longs的指数,您只需转换为double,然后再转换为int / long。或者,您可以创建自己的方法。

它非常直接,因为它是一个扩展功能;只需在.powDouble对象上致电Float

"a^b" -> operand1 = operand1!!/*.toDouble()*/.pow(value)/*.toInt()*/
//Not sure what type operand1 is, so the comments are there if it's not a double or float, and the second assumes it's an int

但是,您可以创建一些中缀函数来获得一个:

这也有两种选择。但是,第一个主要针对Int和Long,它们没有包含pow方法。与投射和使用Math.pow(/ pow扩展功能)相比,我没有对此进行测试。

/**
 * Integer power; manually created
 */
infix fun Int.`**`(exponent: Int): Int{
    var res = 1;
    for(i in exponent downTo 1){
        res *= this
    }
    return res;
}

/**
 * Long power: manually created
 */
infix fun Long.`**`(exponent: Int) : Long{
    var res = 1L;
    for(i in exponent downTo 1){
        res *= this
    }
    return res;
}

或使用Math.pow方法。 我强烈推荐这种方法 - Math.pow is a JNI call

/**
 * Integer power using [Double.pow]
 */
infix fun Int.`**`(exponent: Int): Int = toDouble().pow(exponent).toInt()

/**
 * Long power using [Double.pow]
 */
infix fun Long.`**`(exponent: Int): Long = toDouble().pow(exponent).toLong()

/**
 * Double power using [Double.pow]
 */
infix fun Float.`**`(exponent: Int) : Float = this.pow(exponent)

/**
 * Float power using [Float.pow]
 */
infix fun Double.`**`(exponent: Int) : Double = this.pow(exponent)

有两个注释函数可以使用手动计算代替Double.pow来替代Long和Integer power。

允许您致电:

val x = 10
val exponent = 2
println(x `**` exponent)
assertEquals(x `**` exponent, 100)

注意反引号(``) - 在Kotlin中,它们用于转义关键字并将它们用作实际名称。即var `this`可以是变量名称,但必须称为`this`

如果您不知道infix关键字是什么,它可以启用没有句点和括号的调用函数。这里使用的原因是使x `**` exponent成为实际有效的函数调用。

你也可以选择一个不同的名字来摆脱反引号 - 我只是使用了**,因为它主要是类似Python的(它也用在JavaScript中,也可能用在其他语言中)。

答案 1 :(得分:3)

正如其他答案所述,在Kotlin / Java中没有指数运算符。但是,不建议使用Double和Float中可用的扩展功能来执行Long的幂运算。原因如下: 由于Double的精度限制,取幂后将Double转换回Long可能导致数字舍入。

val EXP = 38

println(3.toDouble().pow(EXP).toLong())
// 1350851717672992000

println(3.toDouble().pow(EXP))
// 1.350851717672992E18 

但是实际答案是13508517176729920 89 。因此,我建议您使用BigIntegers执行幂运算。同样也可以用于快速取模。这是我们最后的pow(base, exp)函数:

fun pow(n: Long, exp: Int): Long{
    return BigInteger.valueOf(n).pow(exp).toLong()
}

答案 2 :(得分:2)

使用扩展方法 pow

inline fun Double.pow(x: Double): Double (source)

了解更多详情pow

答案 3 :(得分:0)

这是解决此问题的另一种方法:

   "a^b" -> operand1 = (operand1!! + 0.0).pow(value + 0.0).toInt()

答案 4 :(得分:-1)

如果您需要一个不依赖于 java.lang 或 Kotlin 的 Double.pow 的跨平台版本,这个简单的实现将起作用:

fun pow(value: Long, exp: Int): Long {
    return when {
        exp > 1 -> value * pow(value,exp-1)
        exp == 1 -> value
        else -> 1
    }
}