在使用 Go 语言进行 JSON 数据处理时,encoding/json 包是我们最常使用的标准库之一。然而,很多初学者在处理包含浮点数的 JSON 数据时,常常会遇到 精度丢失 或 科学计数法显示 等问题。本文将深入浅出地讲解 Go 语言中 encoding/json 包对浮点数的处理机制,并提供实用的解决方案。

Go 语言中的 float64 类型遵循 IEEE 754 标准,它能表示非常大的数值范围,但无法精确表示所有十进制小数(例如 0.1)。当使用 encoding/json 包对结构体进行序列化(Marshal)或反序列化(Unmarshal)时,默认会将浮点数以最紧凑、有效的形式输出,这可能导致:
我们先来看一个简单的例子:
package mainimport ( "encoding/json" "fmt")type Product struct { Name string `json:"name"` Price float64 `json:"price"`}func main() { p := Product{ Name: "笔记本电脑", Price: 9999.99, } data, _ := json.Marshal(p) fmt.Println(string(data))}输出结果:
{"name":"笔记本电脑","price":9999.99}看起来没问题?但如果我们将价格设为更高精度的值,比如 0.1234567890123456789,你会发现输出可能变成 0.12345678901234568 —— 这就是 Go语言浮点数精度 的限制。
在金融、电商等对精度要求极高的场景中,推荐将金额字段定义为字符串类型,并配合 json.Number 或自定义 Marshal/Unmarshal 方法。
package mainimport ( "encoding/json" "fmt" "strconv")type Product struct { Name string `json:"name"` Price string `json:"price"` // 使用 string 保证精度}func main() { p := Product{ Name: "高端显卡", Price: "12345.67890123456789", } data, _ := json.Marshal(p) fmt.Println(string(data)) // 反序列化 var p2 Product json.Unmarshal(data, &p2) fmt.Printf("Price as string: %s\n", p2.Price) // 如需计算,可转为 decimal 库(如 shopspring/decimal) f, _ := strconv.ParseFloat(p2.Price, 64) fmt.Printf("As float64 (may lose precision): %f\n", f)}Go 的 encoding/json 提供了 json.Number 类型,它可以将 JSON 中的数字以字符串形式保留,避免自动转为 float64。
package mainimport ( "encoding/json" "fmt")type Product struct { Name string `json:"name"` Price json.Number `json:"price"`}func main() { // 启用 Number 支持 decoder := json.NewDecoder(strings.NewReader(`{"name":"服务器","price":999999.123456789}`)) decoder.UseNumber() var p Product decoder.Decode(&p) fmt.Printf("Raw number string: %s\n", p.Price) // 输出原始字符串 // 转为 float64(注意仍可能损失精度) f, _ := p.Price.Float64() fmt.Printf("As float64: %f\n", f) // 或转为 string 用于高精度计算 s := string(p.Price) fmt.Printf("As string: %s\n", s)}💡 提示:对于需要高精度计算的场景(如金融系统),建议使用第三方库如
github.com/shopspring/decimal,它基于整数实现,完全避免浮点误差。
通过本文,我们了解了 Go语言JSON序列化精度 问题的根源,并掌握了两种主流解决方案:
string 类型存储高精度数值json.Number 保留原始数字字符串在实际开发中,应根据业务需求选择合适的方式。记住:encoding/json浮点数处理 默认是为通用场景设计的,若涉及金钱、科学计算等敏感数据,请务必采取额外措施确保精度。
希望这篇教程能帮助你彻底理解 Go语言浮点数精度 问题!如有疑问,欢迎在评论区交流。
本文由主机测评网于2025-12-24发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251212101.html