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判断,但本次溢出后结果仍为正数,因此返回falseisOverflow2判断结果是否在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
相关产品推荐
相关产品推荐

