You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift的subtractingReportingOverflow在Kotlin中的等价溢出检测方案?

Kotlin中是否有等价于Swift的subtractingReportingOverflow的溢出检测实现?

Swift的subtractingReportingOverflow会返回运算后的部分值,以及是否发生溢出的标记,示例代码如下:

var someValue = 7212078330627782743
let shiftSize = 5
let shiftedValue = (someValue << shiftSize).subtractingReportingOverflow(someValue)

print("shiftedValue: \(shiftedValue.partialValue)") // 输出 7212078330627782743
print("overflow: \(shiftedValue.overflow)") // 输出 true

你尝试的两种Kotlin判断方法均无法正确检测该场景的溢出:

  • isOverflow1通过结果是否小于0判断,但本次溢出后结果仍为正数,因此返回false
  • isOverflow2判断结果是否在Int范围内,和Long类型的溢出逻辑完全无关,自然无法得到正确结果

正确实现方式

Kotlin可以通过两种方式实现类似Swift的溢出检测逻辑:

方法1:利用标准库精确函数+异常捕获

标准库的shiftLeftExact和subtractExact会在溢出时抛出ArithmeticException,我们可以捕获异常,同时计算静默溢出后的结果:

val someValue = 7212078330627782743L
val shiftSize = 5

var overflow = false
var partialValue: Long = 0
try {
    val shifted = someValue.shiftLeftExact(shiftSize)
    partialValue = shifted.subtractExact(someValue)
} catch (e: ArithmeticException) {
    // 发生溢出,计算静默溢出后的结果
    val shiftedSilent = someValue shl shiftSize
    partialValue = shiftedSilent - someValue
    overflow = true
}

println("partialValue: $partialValue") // 输出 7212078330627782743
println("overflow: $overflow") // 输出 true

方法2:手动判断溢出条件

直接判断移位和减法操作是否触发溢出,返回结果与溢出标记:

// 检测减法操作是否溢出
fun subtractWithOverflow(a: Long, b: Long): Pair<Long, Boolean> {
    val result = a - b
    val overflow = (b > 0 && a < Long.MIN_VALUE + b) || (b < 0 && a > Long.MAX_VALUE + b)
    return Pair(result, overflow)
}

// 检测左移操作是否溢出(Long为64位有符号整数)
fun shiftLeftWithOverflow(x: Long, n: Int): Pair<Long, Boolean> {
    if (n == 0) return Pair(x, false)
    val overflow = x != 0 && (x shr (64 - n)) != 0
    val result = x shl n
    return Pair(result, overflow)
}

val someValue = 7212078330627782743L
val shiftSize = 5

val (shifted, shiftOverflow) = shiftLeftWithOverflow(someValue, shiftSize)
val (partialValue, subtractOverflow) = subtractWithOverflow(shifted, someValue)
val totalOverflow = shiftOverflow || subtractOverflow

println("partialValue: $partialValue") // 输出 7212078330627782743
println("overflow: $totalOverflow") // 输出 true

内容的提问来源于stack exchange,提问作者VIN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:01:01