【问题标题】:JObject.Parse modifies end of floating point valuesJObject.Parse 修改浮点值的结尾
【发布时间】:2014-10-21 10:11:21
【问题描述】:
var clientString = "{\"max\":1214.704958677686}";

JObject o = JObject.Parse(clientString);

var jsonString = o.ToString();

jsonString 的内容:

{
  "max": 1214.7049586776859
}

这既用于可视化对象,也用于执行 ToString()。请注意,686 已神秘地扩展到 6859(添加精度)。这对我们来说是个问题,因为数字不完全一样,而且后面的 json 上的哈希函数不匹配。

【问题讨论】:

  • 这与货币文化无关。不是重复的。
  • 是的,不是完全相同的问题,尽管如果您解析为十进制而不是双精度则可能是这样。我在下面回答你的问题。

标签: json.net


【解决方案1】:

@Ilija Dimov 是正确的——JSON.NET 默认将 JSON 浮点数解析为 doubles。如果您仍想使用 JObject 而不是创建完整的 POCO 进行反序列化,您可以使用 JsonTextReader 并设置 FloatParseHandling 选项:

var reader = new JsonTextReader(new StringReader(clientString));
reader.FloatParseHandling = FloatParseHandling.Decimal;

JObject obj = JObject.Load(reader);

Console.WriteLine(obj["max"].Value<decimal>()); // 1214.704958677686

【讨论】:

    【解决方案2】:

    更改值的原因是 .NET 中浮点数的性质。 JObject.Parse(clientString) 方法有时会执行以下行:

    double d;
    double.TryParse("1214.704958677686", NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d);
    

    其中d 表示您在JObject 中获得的数字。

    由于d 是 double 类型,而 double 是浮点数,所以您没有得到您期望的值。阅读有关Binary floating point and .NET 的更多信息。

    JSON.NET 中有一个选项可以将浮点数解析为小数并获得所需的精度,但要做到这一点,您需要创建与您的 json 字符串匹配的自定义类并反序列化 json。像这样的:

    public class MyClass
    {
        [JsonProperty("max")]
        public decimal Max { get; set; }
    }
    
    
    var obj = JsonConvert.DeserializeObject<MyClass>(clientString, new JsonSerializerSettings
              {
                  FloatParseHandling = FloatParseHandling.Decimal
              });
    

    通过使用此代码示例,max 属性的值不会改变。

    【讨论】:

      【解决方案3】:

      您可以通过解析为浮点数、双精度数和十进制数来试验这种行为:

      Assert.AreEqual(1214.705f,float.Parse("1214.704958677686"));
      Assert.AreEqual(1214.7049586776859, double.Parse("1214.704958677686"));
      Assert.AreEqual(1214.704958677686, decimal.Parse("1214.704958677686"));
      

      所以 json.net 使用 double 作为中间类型。您可以通过设置FloatParseHandling option 来更改此设置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-24
        • 2017-09-19
        • 2019-11-27
        • 1970-01-01
        • 2016-08-10
        • 1970-01-01
        • 2016-07-16
        相关资源
        最近更新 更多