Precision set to only 1 decimal place only in scala if all zeros in precision

Viewed 224

Scala seems to drop all the decimal places and keep just 1 if we convert an Integer to BigDecimal.

How can I tell the compile to preserve the decimal places irrespective of input.

    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

EDIT 1: Some context on why I am trying to preserve the decimal places. I work in a fintech job, where the decimals upto 3 places is mandatory for all amount fields. The scala api is leveraged by Front-End team to show customer balance, reports etc.

1 Answers

From the ScalaDocs page we learn:

In most cases, the value of the BigDecimal is also rounded to the precision specified by the MathContext. To create a BigDecimal with a different precision than its MathContext, use new BigDecimal(new java.math.BigDecimal(...), mc).

And, indeed, that does appear to work.

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

But, unfortunately, the results aren't always consistent.

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

So it would appear that precision is either set by the MathContext or it is whatever is sufficient to accurately represent the stated value, whichever is smaller. (Warning: supposition from limited observation.)

However, if what you need is a consistent presentation of the value then I suggest we move away from MathContext to 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)
Related