Skip to content

数学、随机数与区间

源:Kotlin standard library - Math, Random, Ranges

Kotlin 标准库提供了一套直观且跨平台的 API,用于处理数值计算、随机生成以及范围控制。这些工具不仅简化了常见的数学运算,还通过扩展函数极大地增强了代码的表达力。

边界约束 (Coerce)

在处理数值边界时,我们经常需要编写繁琐的 if-else 来限制值的范围。Kotlin 的 coerce 系列函数是解决这一问题的优雅方案。

kotlin
// 将值限制在 0 到 100 之间
val input = 150
val result = input.coerceIn(0, 100) 
println(result) // 100

// 也可以直接传入闭区间
val bounded = input.coerceIn(0..100)
kotlin
// 确保值不小于 10
val score = 5
println(score.coerceAtLeast(10)) // 10
kotlin
// 确保值不大于 50
val speed = 100
println(speed.coerceAtMost(50)) // 50

跨平台随机数 (Random)

Kotlin 提供了一个全局唯一的 kotlin.random.Random 对象,它在 KMP 项目中具有一致的表现,建议在 Kotlin 代码中全面取代 java.util.Random

基础生成

kotlin
import kotlin.random.Random

val nextInt = Random.nextInt(0, 100) // [0, 100)
val nextDouble = Random.nextDouble() // [0.0, 1.0)
val nextBoolean = Random.nextBoolean()

容器随机操作

kotlin
val list = listOf("Apple", "Banana", "Cherry")

// 随机取一个元素
val fruit = list.random()

// 随机打乱集合
val shuffled = list.shuffled()

区间进阶 (Ranges & Progressions)

除了基础的 1..10,Kotlin 提供了更灵活的区间控制方式。

常用构建方式

  • ..:闭区间(包含首尾),如 1..10 包含 10。
  • until:半开区间(不含末尾),如 1 until 10 不含 10。
  • downTo:逆序区间,如 10 downTo 1
  • step:步长,如 (1..10) step 2 会产生 1, 3, 5, 7, 9。
kotlin
for (i in 1 until 5) print(i) // 1234
for (i in 5 downTo 1 step 2) print(i) // 531

区间的检查与操作

区间不仅可以用于循环,还可以作为逻辑判断。

kotlin
val range = 1..100

if (50 in range) {
    println("50 在范围内")
}

// 获取区间的第一个、最后一个和步长
println(range.first)
println(range.last)
println(range.step)

数学函数 (Math)

Kotlin 在 kotlin.math 包中重写了所有的数学函数,这些函数通常是顶层函数,可以直接调用而不需要 Math. 前缀。

kotlin
import kotlin.math.*

val absolute = abs(-10)        // 绝对值
val root = sqrt(16.0)         // 平方根
val power = 2.0.pow(3)        // 幂运算 (2 的 3 次方)
val rounded = round(3.5)      // 四舍五入

// 常用常量
val circle = 2 * PI
val e = E

精度注意

在进行浮点数计算时,始终注意 FloatDouble 的精度问题。对于财务等高精度要求的场景,在 JVM 上仍建议使用 BigDecimal

最佳实践

  1. 废弃 java.util.Random:在 Kotlin 代码中,尤其是 KMP 项目,始终使用 kotlin.random.Random 以获得更好的跨平台兼容性和更简洁的 API。
  2. 用 coerce 代替 if-else:在做 UI 动画位置限制或滑动范围计算时,coerceIn 能让逻辑一目了然。
  3. 使用 until 避免索引越界:遍历数组或列表索引时,0 until size0..size-1 更符合直觉且不易出错。