首页 > 解决方案 > 如果精度全为零,则精度仅在 scala 中设置为小数点后 1 位

问题描述

如果我们将 Integer 转换为 BigDecimal,Scala 似乎会删除所有小数位并仅保留 1。

无论输入如何,我如何告诉编译保留小数位。

    scala> val tmp:BigDecimal = 1.00
    tmp: BigDecimal = 1.0
// was expecting 1.00

    scala> val tmp:BigDecimal = 1.01
    tmp: BigDecimal = 1.01

    scala> val tmp:BigDecimal = 1.11
    tmp: BigDecimal = 1.11

编辑1:关于我为什么要保留小数位的一些背景信息。我从事金融科技工作,所有金额字段都必须保留小数点到 3 位。前端团队利用 scala api 来显示客户余额、报告等。

标签: scala

解决方案


ScalaDocs 页面我们了解到:

在大多数情况下,BigDecimal 的值也会四舍五入到 MathContext 指定的精度。要创建精度与其 MathContext 不同的 BigDecimal,请使用new BigDecimal(new java.math.BigDecimal(...), mc).

而且,确实,这似乎确实有效。

import java.math.{BigDecimal=>JBD, MathContext=>JMC}

val a = BigDecimal(2.4)                      //a: scala.math.BigDecimal = 2.4
a.precision                                  //res0: Int = 2

val b = BigDecimal(new JBD(2.4, new JMC(7))) //b: scala.math.BigDecimal = 2.400000
b.precision                                  //res1: Int = 7

但是,不幸的是,结果并不总是一致的。

import java.math.{BigDecimal=>JBD, MathContext=>JMC}

val a = BigDecimal(2.5)                      //a: scala.math.BigDecimal = 2.5
a.precision                                  //res0: Int = 2

val b = BigDecimal(new JBD(2.5, new JMC(7))) //b: scala.math.BigDecimal = 2.5
b.precision                                  //res1: Int = 2

因此,似乎精度要么由 设置,要么MathContext足以准确表示所述值,以较小者为准。(警告:来自有限观察的假设。)

但是,如果您需要的是对价值的一致表示,那么我建议我们从MathContextto移开StringContext

val a :BigDecimal = 1
val b :BigDecimal = 2.2
val c :BigDecimal = 3.456

f"$a%.2f"  //res0: String = 1.00
f"$b%.2f"  //res1: String = 2.20
f"$c%.2f"  //res2: String = 3.46 (note the rounding)

推荐阅读