插件窝 干货文章 Go语言float64精度丢失:如何保证JSON输出保留小数点后两位零?

Go语言float64精度丢失:如何保证JSON输出保留小数点后两位零?

JSON MyStruct Value formattedValue 537    来源:    2025-03-13

在Go语言中,处理浮点数精度问题时,尤其是在JSON输出中保留小数点后两位零,可以通过以下几种方式来实现:

1. 使用strconv.FormatFloat格式化浮点数

你可以先将float64类型的浮点数格式化为字符串,确保保留两位小数,然后再将其转换为JSON。

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type MyStruct struct {
    Value string `json:"value"`
}

func main() {
    value := 123.456
    formattedValue := strconv.FormatFloat(value, 'f', 2, 64)

    myStruct := MyStruct{Value: formattedValue}
    jsonData, err := json.Marshal(myStruct)
    if err != nil {
        fmt.Println("Error marshalling JSON:", err)
        return
    }

    fmt.Println(string(jsonData))
}

2. 使用json.Marshaljson.Number类型

你可以使用json.Number类型来保留浮点数的精度,并在输出时手动控制小数位数。

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type MyStruct struct {
    Value json.Number `json:"value"`
}

func main() {
    value := 123.456
    formattedValue := strconv.FormatFloat(value, 'f', 2, 64)

    myStruct := MyStruct{Value: json.Number(formattedValue)}
    jsonData, err := json.Marshal(myStruct)
    if err != nil {
        fmt.Println("Error marshalling JSON:", err)
        return
    }

    fmt.Println(string(jsonData))
}

3. 使用fmt.Sprintf格式化浮点数

你也可以使用fmt.Sprintf来格式化浮点数,确保保留两位小数。

package main

import (
    "encoding/json"
    "fmt"
)

type MyStruct struct {
    Value string `json:"value"`
}

func main() {
    value := 123.456
    formattedValue := fmt.Sprintf("%.2f", value)

    myStruct := MyStruct{Value: formattedValue}
    jsonData, err := json.Marshal(myStruct)
    if err != nil {
        fmt.Println("Error marshalling JSON:", err)
        return
    }

    fmt.Println(string(jsonData))
}

4. 自定义JSON序列化

如果你需要更复杂的控制,可以实现自定义的JSON序列化方法。

package main

import (
    "encoding/json"
    "fmt"
)

type MyStruct struct {
    Value float64 `json:"value"`
}

func (m MyStruct) MarshalJSON() ([]byte, error) {
    formattedValue := fmt.Sprintf("%.2f", m.Value)
    return json.Marshal(map[string]string{
        "value": formattedValue,
    })
}

func main() {
    myStruct := MyStruct{Value: 123.456}
    jsonData, err := json.Marshal(myStruct)
    if err != nil {
        fmt.Println("Error marshalling JSON:", err)
        return
    }

    fmt.Println(string(jsonData))
}

总结

以上方法都可以确保在JSON输出中保留小数点后两位零。选择哪种方法取决于你的具体需求和代码结构。如果你只需要简单的格式化,strconv.FormatFloatfmt.Sprintf是最直接的选择。如果你需要更复杂的控制,自定义JSON序列化方法可能更适合。