Kotlin中如何对Double类型执行精确的rem求余运算
Double类型精确求余解决方案
问题根因
Double是IEEE 754标准的二进制浮点数类型,无法精确表示0.2这类不属于2的负整数次幂的十进制小数,代码中写入的0.2实际存储的是一个非常接近0.2的近似值。Double.rem方法的逻辑本身符合注释描述,但参与运算的两个输入值本身就存在精度误差,因此最终得到的余数不是预期的0.0。
可行方案
方案1:使用BigDecimal做精确运算(最推荐)
直接将浮点数转换为BigDecimal执行求余运算,注意必须用字符串构造BigDecimal,避免从Double转换时带入原有精度误差:
import java.math.BigDecimal fun main() { val a = BigDecimal("10.0") val b = BigDecimal("0.2") val remainder = a.remainder(b) println(remainder) // 输出 0.0 }
方案2:放大为整数运算(适合小数位固定场景)
如果业务场景中小数的位数是固定的(比如最多2位小数的金额、最多1位小数的度量值),可以先将数值放大对应倍数转为整数运算,完成后再缩小回去:
fun main() { // 示例中最多1位小数,放大10倍 val scale = 10 val a = (10.0 * scale).toLong() val b = (0.2 * scale).toLong() val remainder = (a % b).toDouble() / scale println(remainder) // 输出 0.0 }
方案3:结果四舍五入(仅适合输出展示场景)
如果只需要最终输出符合预期,不需要后续运算,可以对求余结果按需求保留小数位:
fun main() { val res = 10.0 % 0.2 // 保留1位小数四舍五入 println("%.1f".format(res)) // 输出 0.0 }
内容的提问来源于stack exchange,提问作者Matt Groth
相关产品推荐
相关产品推荐

