Search code examples
scalaargonaut

Incorrect Float conversion by Argonaut.io


I convert Float field of object to json. And value 0.6 converts to 0.6000000238418579 by Argonaut. How to correct it?

Simple test case to check this:

import argonaut.Argonaut._
import argonaut.EncodeJson

class Person(val name: Float)
val person = new Person(0.6f)
println("#1")
println(person.name)
def PersonEncodeJson: EncodeJson[Person] =
  EncodeJson((p: Person) => ("name" := p.name) ->: jEmptyObject)
val json = person.asJson(PersonEncodeJson).nospaces
println("#2")
println(json)

Console output:

#1
0.6
#2
{"name":0.6000000238418579}

Solution

  • Do you have to be using Float? Since you care about the exact value, it doesn't seem appropriate.

    Example using BigDecimal instead:

    import argonaut.Argonaut._
    import argonaut.EncodeJson
    
    class Person(val name: BigDecimal)
    val person = new Person(BigDecimal("0.6"))
    
    def PersonEncodeJson: EncodeJson[Person] =
      EncodeJson((p: Person) => ("name" := p.name) ->: jEmptyObject)
    
    person.asJson(PersonEncodeJson).nospaces
    // res0: String = {"name":0.6}
    

    Or if you can't change the Person class, you can convert the Float to String and then to BigDecimal:

    import argonaut.Argonaut._
    import argonaut.EncodeJson
    
    class Person(val name: Float)
    val person = new Person(0.6f)
    
    def PersonEncodeJson: EncodeJson[Person] =
      EncodeJson((p: Person) =>
        ("name" := BigDecimal(p.name.toString)) ->: jEmptyObject)
    
    person.asJson(PersonEncodeJson).nospaces
    // res0: String = {"name":0.6}