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

Scala除法运算与取整问题求助:如何让结果保留两位小数?

解决Scala中BigDecimal除法的小数位控制问题

首先,咱们来拆解一下你遇到的两个核心问题:

第一个异常的根源

你最初的代码抛出java.lang.ArithmeticException: Non-terminating decimal expansion,本质原因是BigDecimal在除法运算时,若结果是无限循环小数,默认不会自动执行舍入操作——它要求必须明确指定舍入规则,否则就会抛出这个异常,以此避免隐式的精度丢失。

为什么转Double的方案达不到预期?

你改成转Double后再做除法,结果出现一堆冗余小数位,问题出在两点:

  • Double是浮点数,本身精度有限,把BigDecimal转成Double的过程就可能已经丢失了精确性;
  • Double的除法运算结果也是浮点数,无法精确控制小数位数,自然会出现多余的小数位,而且这种方式也达不到你想要的精确舍入效果。

正确的解决方案:全程用BigDecimal处理

要实现除法结果仅保留两位小数,你应该在BigDecimal的运算阶段就指定舍入规则,全程避免转成Double。有两种简洁且严谨的写法:

写法一:先除法再设置小数位

val ratio = (order.price.toBigDecimal / order.subPrice.toBigDecimal)
  .setScale(2, BigDecimal.RoundingMode.HALF_UP)
  .toString

写法二:除法时直接指定精度(更直观)

val ratio = order.price.toBigDecimal.divide(
  order.subPrice.toBigDecimal,
  2,
  BigDecimal.RoundingMode.HALF_UP
).toString

这两种写法的效果完全一致:

  1. 全程用BigDecimal运算,保证数值精度不丢失;
  2. 通过setScale或divide的参数明确指定保留2位小数,采用四舍五入(HALF_UP)的舍入模式;
  3. 最终转成字符串后就是你想要的两位小数格式,比如9.84而不是一堆冗余的小数位。

额外补充:如果需要取整

要是你的需求是得到整数结果(比如把9.84变成10或9),只需要把setScale的第一个参数改成0即可:

val integerResult = (order.price.toBigDecimal / order.subPrice.toBigDecimal)
  .setScale(0, BigDecimal.RoundingMode.HALF_UP)
  .toString

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:45:30