如何在Go中编码为JSON时以十进制格式强制执行浮点运算

时间:2017-11-17 01:12:12

标签: json go

我有一个big.float,我编码成JSON。然而,JSON总是以科学记数法表示浮点数而不是十进制表示法。我可以通过将JSON更改为字符串而不是数字并使用float.Text(' f')来解决这个问题,但我真的更愿意将类型保留为数字。

我是在看float.Format,但我不相信这是合适的。

我正在做的一个非常浓缩的要点如下。在将它编码为json之前,我对supply的值做了很多修改。

type TokenSupply struct {
   TotalSupply  *big.Float  `json:"totalSupply, omitempty"`
}
supply := Float.NewFloat(1000000)
json.NewEncoder(w).Encode(TokenSupply{supply})

返回:

{"totalSupply":"1e+06"}

2 个答案:

答案 0 :(得分:2)

big.Float在转换为JSON类型时被编组为字符串

https://golang.org/pkg/encoding/json/#Marshal

  

Marshal以递归方式遍历值v。如果遇到的值实现了Marshaler接口并且不是nil指针,Marshal会调用其MarshalJSON方法来生成JSON。如果不存在MarshalJSON方法,但该值实现 encoding.TextMarshaler ,则Marshal调用其MarshalText方法并将结果编码为JSON字符串。 nil指针异常不是绝对必要的,但在UnmarshalJSON的行为中模仿了类似的必要异常。

https://golang.org/pkg/math/big/#Float.MarshalText

func (x *Float) MarshalText() (text []byte, err error)

你能做些什么?

因为你的浮点数可能超过64位,所以它不能与其他必须将JSON值作为数字读取的语言一起使用。我建议你把数字保留为字符串。

答案 1 :(得分:0)

关于编码不适合64位的数字的注意事项,以下是通过将big.Float包装为实现json.Marshaler的自定义类型,将MarshalJSON编组为JSON编号的方法。关键是你可以随意实现package main import ( "encoding/json" "fmt" "math/big" ) type BigFloatNumberJSON struct{ *big.Float } func (bfn BigFloatNumberJSON) MarshalJSON() ([]byte, error) { // Use big.Float.String() or any other string converter // that emits a valid JSON number here... return []byte(bfn.String()), nil } func main() { totalSupply := new(big.Float).SetFloat64(1000000) obj := map[string]interface{}{ "totalSupply": BigFloatNumberJSON{totalSupply}, } bytes, err := json.Marshal(&obj) if err != nil { panic(err) } fmt.Println(string(bytes)) // => {"totalSupply":1000000} } 方法,只要它发出有效的JSON:

{{1}}