避坑:C# json反序列化为float精度丢失
在 C# 中将 JSON 反序列化为 float
时,确实容易出现精度丢失的问题,主要原因包括:
float
和double
是 IEEE 754 浮点数,无法精确表示某些十进制小数;- JSON 中的数值是十进制字符串,反序列化时被强制转成二进制浮点数,导致精度误差。
✅ 避坑方案
✅ 1. 使用 decimal
类型替代 float
decimal
是十进制浮点类型,精度更高,适合金融、金额等场景。
public class MyData
{public decimal Value { get; set; } // 推荐
}
实测:将 0.4064
作为 float
会丢失精度,而作为 decimal
不会 。
✅ 2. 使用 System.Text.Json
的 GetRawText()
保留原始字符串
如果你必须用字符串形式读取 JSON 中的数值(如科学计数法 "5e-0000006"
),可以使用:
using System.Text.Json;var json = "{\"myfield\":5e-0000006}";
using var doc = JsonDocument.Parse(json);
var rawValue = doc.RootElement.GetProperty("myfield").GetRawText();
Console.WriteLine(rawValue); // 输出:5e-0000006
适用于需要精确记录原始格式的场景 。
✅ 3. Newtonsoft.Json 中用字符串接收数字
使用 JsonProperty
将数字字段反序列化为字符串,避免精度问题:
public class MyJson
{[JsonProperty("myfield")]public string MyField { get; set; }
}
❗不推荐的做法
- 不建议用
float
或double
接收高精度小数 JSON 字段; - 不建议依赖正则提取 JSON 中的数值字段,除非解析器无法满足需求 。
✅ 总结建议
场景 | 推荐做法 |
---|---|
需要高精度计算 | 使用 decimal |
需要保留原始字符串格式 | 使用 GetRawText() 或字符串 |
不需要精度(如图形坐标) | float /double 可接受 |
如需进一步处理高精度 JSON 数值(如科学计数法或超长小数),建议使用 decimal
或自定义 JsonConverter
进行转换。