【问题标题】:Incorrect Float conversion by Argonaut.ioArgonaut.io 的浮点数转换不正确
【发布时间】:2015-08-26 06:47:24
【问题描述】:

我将对象的Float 字段转换为json。并且值 0.6 转换为 Argonaut 的 0.6000000238418579。如何纠正?

简单的测试用例来检查这个:

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)

控制台输出:

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

【问题讨论】:

  • 你怎么知道是argonaut问题?你是否传递了一个文字 0.6 变成了 0.6000000238418579?大多数数字不能用浮点数精确表示。
  • @Simon 我更新了问题以提供证据。

标签: scala argonaut


【解决方案1】:

你必须使用Float吗?由于您关心确切的值,因此它似乎不合适。

使用BigDecimal 代替的示例:

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}

或者如果您无法更改Person 类,您可以将Float 转换为String,然后再转换为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}

【讨论】:

    【解决方案2】:

    在处理浮动时,这种事情是很正常的。

    scala> val a = 0.6f
    a: Float = 0.6
    
    scala> val b: Double = a
    b: Double = 0.6000000238418579
    

    为确保不会发生这种情况,您可以在添加到 JSON 之前格式化浮点数

    def PersonEncodeJson: EncodeJson[Person] = EncodeJson((p: Person) => ("name" := "%1.1f" format p.name) ->: jEmptyObject)
    

    【讨论】:

    • 这是一个糟糕的解决方案,因为我需要 json 中的 number 字段类型,而不是 string。但是您指出问题是FloatDouble 之间的转换,现在我知道我应该探索的问题了。
    • @Lunigorn 也许 Chris Martins 的回答(使用 BigDecimal)是你需要的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    相关资源
    最近更新 更多