插件窝 干货文章 Go语言float64精度丢失:如何避免JSON输出时小数点后零丢失?

Go语言float64精度丢失:如何避免JSON输出时小数点后零丢失?

序列化 小数点 strconv FormatFloat 481    来源:    2025-03-14

在Go语言中,当你将float64类型的数据序列化为JSON时,默认情况下,小数点后的零可能会被省略。例如,1.0可能会被序列化为1。如果你希望保留小数点后的零,可以通过自定义JSON序列化来实现。

解决方案

  1. 自定义JSON序列化: 你可以通过实现json.Marshaler接口来自定义float64类型的序列化行为。具体步骤如下:

    package main
    
    import (
       "encoding/json"
       "fmt"
       "strconv"
    )
    
    // 定义一个自定义类型,用于包装float64
    type Float64 float64
    
    // 实现json.Marshaler接口
    func (f Float64) MarshalJSON() ([]byte, error) {
       // 使用strconv.FormatFloat将float64转换为字符串,保留小数点后的零
       return []byte(strconv.FormatFloat(float64(f), 'f', -1, 64)), nil
    }
    
    func main() {
       data := map[string]interface{}{
           "value": Float64(1.0),
       }
    
       jsonData, err := json.Marshal(data)
       if err != nil {
           fmt.Println("Error:", err)
           return
       }
    
       fmt.Println(string(jsonData)) // 输出: {"value":1.0}
    }
    

    在这个例子中,我们定义了一个Float64类型,并为其实现了MarshalJSON方法。在MarshalJSON方法中,我们使用strconv.FormatFloat函数将float64转换为字符串,并保留小数点后的零。

  2. 使用strconv.FormatFloat: 如果你不想自定义类型,也可以直接在序列化时使用strconv.FormatFloat来格式化浮点数:

    package main
    
    import (
       "encoding/json"
       "fmt"
       "strconv"
    )
    
    func main() {
       value := 1.0
       formattedValue := strconv.FormatFloat(value, 'f', -1, 64)
    
       data := map[string]interface{}{
           "value": formattedValue,
       }
    
       jsonData, err := json.Marshal(data)
       if err != nil {
           fmt.Println("Error:", err)
           return
       }
    
       fmt.Println(string(jsonData)) // 输出: {"value":"1.0"}
    }
    

    这种方法将浮点数转换为字符串后再进行序列化,从而保留了小数点后的零。

总结

通过自定义JSON序列化或使用strconv.FormatFloat函数,你可以避免在JSON输出时丢失float64类型数据的小数点后的零。选择哪种方法取决于你的具体需求和应用场景。