编写BigDecimal计算,好像它只是Scala中通常的四个算术运算一样

sui*_*ish 3 scala bigdecimal bigint

我目前正在研究Scala,并对它有多好感到惊讶.我认为它的BigDecimal一个重点是它如何处理类型.一旦定义一个BigDecimal你可以使用它几乎就像它Int或Double

val foo:BigDecimal = 0.1
println(foo + 0.2) // 0.3
Run Code Online (Sandbox Code Playgroud)

有没有必要使用.multiply()或.add()只是简单+或*处理BigDecimal的计算(我假设BigDecimal的+/ *最终调用他们的这里面虽然).它真的很容易,即使读,如果计算变得复杂,除一件事,你必须先申报计算值为BigDecimal.

println(0.3 * (BigDecimal(0.1) + 0.2))
Run Code Online (Sandbox Code Playgroud)

我的问题是,我怎么能写这样的代码呢?

println(0.3 * (0.1 + 0.2))
Run Code Online (Sandbox Code Playgroud)

我假设这需要覆盖数字类型的文字.

提前致谢.

Kol*_*mar 6

我认为你不能覆盖数字文字.你可以做的是使用字符串插值或添加方法来简化语法Double.

// With string interpolation
implicit class BigDecimalStringContext(private val sc: StringContext) extends AnyVal {
  def d(args: Any*): BigDecimal = {
    val stringRepr = sc.s(args: _*)
    BigDecimal(stringRepr)
  }
}

println(d"0.3" * (d"0.1" + d"0.2"))
println(0.3 * (d"0.1" + 0.2))


// Pimp my library 
implicit class DoubleOps(private val d: Double) extends AnyVal {
  def bd = BigDecimal(d)
}

println(0.3.bd * (0.1.bd + 0.2.bd))
println(0.3 * (0.1.bd + 0.2))
Run Code Online (Sandbox Code Playgroud)

第一种方法更安全,因为第二种方法试图转换a Double,因此可能会失去精度:

scala> 0.123456789012345678901234567890.bd * (0.1.bd + 0.2.bd)
res1: scala.math.BigDecimal = 0.037037036703703704

scala> d"0.123456789012345678901234567890" * (d"0.1" + d"0.2")
res2: scala.math.BigDecimal = 0.0370370367037037036703703703670
Run Code Online (Sandbox Code Playgroud)