什么是Kotlin指数运算符

什么是Kotlin指数运算符,kotlin,Kotlin,Kotlin中的指数运算符是什么。我假设它是**,但它似乎在我的代码中抛出了一个错误 when (pendingOperation) { "=" -> operand1 = value "÷" -> operand1 = if (value == 0.0) { Double.NaN // handle attempt to divide by zero } else { operand1!! / value }

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

使用扩展方法pow

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

更详细地说,Kotlin与Java一样,没有指数运算符。Java有
Math.pow
,您也可以将其与Kotlin一起使用,但是Kotlin还可以使用Float和Double的扩展函数

如果需要将指数与int或long一起使用,只需将其转换为double,然后再转换回int/long即可。或者,您可以创建自己的方法

这很简单,因为它是一个扩展函数;只需在
Double
Float
对象上调用
.pow

"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
注意:由于,此答案的其余部分在Android上不起作用。改用
.pow()
Math.pow()
。这仍然适用于JVM(可能还有Kotlin Native),但不适用于Android


但是,您可以创建一些中缀函数来获得一个。这里的想法是使用Kotlin名称的转义字符来创建Python风格的指数运算符。逃逸游戏很有趣,但可以带来很多乐趣。您还可以使用带有空格的名称,假设您将其用倒勾(`)括起来

你也可以从头开始编写自己的幂函数,但是注意 Maul.Po.()/Cyt>的实现是用C++编写的,而且最有可能比用KOTLIN或java编写的更快。

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

/**
 * Long power using [Double.pow]
 * Note: it may be preferable to use a BigInteger instead of toDouble()
 * to prevent a loss of precision - use whichever makes sense
 * for the number you have at hand.
 */
infix fun Long.`**`(exponent: Int): Long = toDouble().pow(exponent).toLong()
// infix fun Long.`**`(exponent: Int): Long = toBigInteger().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)
允许您拨打:

val x = 10
val exponent = 2
println(x `**` exponent)
assertEquals(x `**` exponent, 100)
注意倒勾(
`
)。正如我前面提到的,在Kotlin中,当函数、变量、类或其他东西包含Kotlin关键字时,这些函数用于转义java调用。例如,如果我在Java中声明了一个
boolean is()
,并想从Kotlin调用它,那么我必须将它称为
ContainingClass.`is`

但是,它们不限于在调用Java函数或变量时使用。您可以将它们用作实际变量或函数名。例如,
var`this`
可以是一个变量名,但必须作为
`this`
调用/取消引用

例如,这是完全有效的代码:

var `this` = 32
`this` += 10;
print(`this`)
。。。但是如果您在类中运行它,并使用
print(this)
而不是使用
print(`this`)
,那么您将打印类“
toString()
方法的结果,而不是42


此外,backticks不关心逃逸的内容。不管Kotlin关键字与否,所有内容都将转义。您可以使用空格、符号、表情符号(因此您最终可以使用
val`,正如其他答案所述,Kotlin/Java中没有指数运算符。但是,不建议使用Double和Float中提供的扩展函数来执行Long的指数运算。原因如下:
由于Double的精度限制,将Double转换回Long after求幂可能导致数字的舍入

val EXP = 38

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

println(3.toDouble().pow(EXP))
// 1.350851717672992E18 
但实际答案是1350851717672992089。因此,我建议您使用大整数执行幂运算。同样的方法也可用于快速模幂运算。下面是我们的最终
pow(base,exp)
函数:

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

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

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

如果您需要一个不依赖于
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
    }
}

使用反勾号(``)定义函数名只能在测试中使用!android平台(DEX文件)也不支持@问:安卓先生从未在问题中提及过,我也不打算在没有列出安卓的时候以安卓作为我的主要关注点来写答案。就像安卓不是Java一样,Kotlin安卓也不是Kotlin。使用
.pow()
Math#pow()
instead@Mr.Qbackticks主要用于促进Java Kotlin的互操作。它不限于测试,至少对实际的Kotlin是这样。一篇关于它的帖子建议它是Android DEX的东西,在这种情况下,它不能被使用。这仍然适用于Kotlin-Android从来不是解决方案的预期目标。你获得外观的原因是它只适用于测试是因为标准测试(非androidTest)在JVM上运行,而非Dalvik。真正的JVM(如非Dalvik)仍然支持它。这使用了未在Kotlin中优化的尾部递归。该算法效率非常低,对于
exp
>>pow(1000000)的大值,将堆栈溢出
java.lang.StackOverflowerError
实际上pow(1,无论什么)将立即退出而不递归。在堆栈溢出之前,您将溢出MAX_LONG。但您是对的,递归可能会对大指数造成问题,因此如果您担心的话,可以将其重写为循环。