-1

Given

{  "currency" : {
       "details" : {
     "data" : {
       "code" : "INR",
       "name" : "Indian Rupee",
       "symbol" : "₹"
     }
   }
 },
 "amt" : 3.247913577689E10
}

problem: The above json I am getting as a response in my code from that, I am taking out the amt and then sending back the amt amount in a file. But the problem is amt is coming in scientific notation. I have tried code like given below

val paymentAmount = (json \ "total_amount").extractOrElse(0.00).toString

It is not working. I tried f interpolation but for biggest number it is rounding off. How to handle this?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
v1235
  • 11
  • 1
    Your json doesn't have `"total_amount"`. With `"amt"` your code seems to work https://scastie.scala-lang.org/N4R0xNm5R5O2tVg7PnrAMQ – Dmytro Mitin Oct 14 '20 at 23:24
  • BEWARE: Both [Json4s](https://github.com/json4s/json4s/issues?utf8=%E29C%93&q=is%3Aissue+is%3Aopen+denial) and [Java's and Scala's BigDecimal](https://stackoverflow.com/questions/58757818/scala-math-bigdecimal-1-2-and-1-20-are-equal/58777171#58777171) are vulnerable under DoS/DoW attacks! – Andriy Plokhotnyuk Oct 22 '20 at 06:15

1 Answers1

1

I don't know what exactly json library you use, but it parses easy with play json

  val json = """{
               |    "currency": {
               |        "details": {
               |            "data": {
               |                "code": "INR",
               |                "name": "Indian Rupee",
               |                "symbol": "₹"
               |            }
               |        }
               |    },
               |    "amt": 3.247913577689E10
               |}
               |""".stripMargin

  def main(args: Array[String]): Unit = {
    import play.api.libs.json._
    val paymentAmount: Double = (Json.parse(json) \ "amt").as[Double]
    println(paymentAmount) // 3.247913577689E10
  }
Oleg Zinoviev
  • 549
  • 3
  • 14
  • Maybe json4s (because of `extractOrElse` and ``\``). – Dmytro Mitin Oct 14 '20 at 23:13
  • i am using json4s, and the paymentAmount is coming is in scientific notation which I don't want to display. how to avoid this – v1235 Oct 15 '20 at 02:39
  • I used f" $paymentAmount%.2f" this to avoid scientific notation. but, is there any other way to avoid roundoff and scientific notation both. – v1235 Oct 15 '20 at 02:49
  • paymentAmount should have come as 32479135776.89, although in the json amt is given in scientific notation but while extract we can avoid this. – v1235 Oct 15 '20 at 02:52
  • scala> BigDecimal(f"$paymentAmount%.2f", new MathContext(0, RoundingMode.CEILING)) to avaoid both, but this also not working – v1235 Oct 15 '20 at 03:38
  • @v1235, why don't you use just `BigDecimal(paymentAmount)` ? It gives `32479135776.89` – Oleg Zinoviev Oct 15 '20 at 07:09
  • scala> BigDecimal(3.247913577689E10) res37: scala.math.BigDecimal = 32479135776.89 yes, it is coming correct , but what if number is bigger than that. – v1235 Oct 15 '20 at 07:28
  • scala> BigDecimal(9.9999474687648691E17) res38: scala.math.BigDecimal = 9.9999474687648691E+17 – v1235 Oct 15 '20 at 07:28
  • for the 2nd number 9.9999474687648691E17 how i handle this, – v1235 Oct 15 '20 at 07:29
  • @v1235 the only thing I can advise is to convert scala `BigDecimal` to java one and use then `toPlainString` on java instance. It's not optimal from performance perspective, but maybe the performance is not your bottle neck. It will look like this: `BigDecimal("9.9999474687648691E17").bigDecimal.toPlainString`. and give `999994746876486910` – Oleg Zinoviev Oct 15 '20 at 08:34
  • the above solution is not working, it is rounding off the the number which I don't want – v1235 Oct 16 '20 at 02:15
  • is there any way to avoid the scientific notation in json itself, like when I get the above json from HTTP call, it gives me correct data without any scientific notation? – v1235 Oct 16 '20 at 02:16