JSON以相同的方式序列化两个十进制数字

Posted

技术标签:

【中文标题】JSON以相同的方式序列化两个十进制数字【英文标题】:JSON Serialize two decimal numbers the same way 【发布时间】:2013-08-12 16:39:13 【问题描述】:

如何强制 NewtonSoft Json 序列化器以相同的方式序列化两个小数?

decimal a = 1234.1200M;
decimal b = 1234.12M;

var sa = JsonConvert.SerializeObject(new  value = a );
var sb = JsonConvert.SerializeObject(new value = b);
Console.WriteLine(sa);
Console.WriteLine(sb);

结果是: “价值”:1234.1200 “价值”:1234.12

如何强制它用 4 位小数对它们进行序列化,以便结果相同?

【问题讨论】:

有点小技巧,删除M 之前的尾随零。很高兴在这里见到你 +1 【参考方案1】:

您可以按如下方式格式化小数:

        var sa = JsonConvert.SerializeObject(new  value = a.ToString("#.#000") );
        var sb = JsonConvert.SerializeObject(new  value = b.ToString("#.#000") );

【讨论】:

但这是一个字符串而不是小数。您的结果将是"value": "1234.1200"。此外,当小数是更复杂对象的一部分时,这不起作用,而不仅仅是我在示例中使用的简单版本。 如果您想将其视为小数,“1234.1200”和“1234.12”之间没有任何区别。您要求的是字符串表示形式的差异。有人可以说,你是在让它像小数一样走路,像弦一样嘎嘎……【参考方案2】:

在稍微摆弄一下序列化程序后,我找到了一个“答案”:

private class JsonTextWriterOptimized : JsonTextWriter

    public JsonTextWriterOptimized(TextWriter textWriter)
        : base(textWriter)
    
    
    public override void WriteValue(decimal value)
    
        // we really really really want the value to be serialized as "0.0000" not "0.00" or "0.0000"!
        value = Math.Round(value, 4);
        // divide first to force the appearance of 4 decimals
        value = Math.Round((((value+0.00001M)/10000)*10000)-0.00001M, 4); 
        base.WriteValue(value);
    

第一个 Math.Round 将在第 4 个之后删除所有小数。 值+0.00001M 完成后,像 100 这样的数字变为 100.00001。然后我们乘除。所有这一切都使小数点坚持到小数点后 4 位。然后我们四舍五入以确保我们通过 +0.00001 添加的第 5 位小数消失了。 这似乎适用于我提出的任何价值观。

然后使用自定义编写器:

var jsonSerializer = Newtonsoft.Json.JsonSerializer.Create();
var sb = new StringBuilder(256);
var sw = new StringWriter(sb, CultureInfo.InvariantCulture);
using (var jsonWriter = new JsonTextWriterOptimized(sw))

    jsonWriter.Formatting = Formatting.None;
    jsonSerializer.Serialize(jsonWriter, instance);

我还修正了自己的答案(我忘记了类似的问题): Serializing a decimal to JSON, how to round off?

【讨论】:

以上是关于JSON以相同的方式序列化两个十进制数字的主要内容,如果未能解决你的问题,请参考以下文章

使用 DataAnnotation 序列化 JSON 以应用十进制格式规则

c++两个自然数(输入的十进制数转换为二进制时,两个数的位数相同。) 输出:有效则有效,无效则无效

Java千问:各种数制及数制间转换算法详解

P1143 进制转换

P1143 进制转换

为什么要在JSON中使用字符串来表示十进制数