简体   繁体   English

使用GSON序列化BigDecimal值

[英]Serializing BigDecimal value using GSON

here is my code: 这是我的代码:

System.out.println(GSON.toJson(new BigDecimal(10.12)));

and the output is: 输出是:

10.1199999999999992184029906638897955417633056640625

Is it possible to limit the precision of BigDecimal value that GSON serialize? 是否可以限制GSON序列化的BigDecimal值的精度? ie my expected output of serialized value is: 即我的序列化值的预期输出是:

10.11

The problem here isn't with GSON but with your BigDecimal value instead. 这里的问题不是GSON,而是你的BigDecimal值。

If you use the new BigDecimal(double value) constructor you can have unpredictable results. 如果使用new BigDecimal(double value)构造函数,则可能会产生不可预测的结果。

If you take a look at BigDecima(double value) constructor documentation it clearly says : 如果你看看BigDecima(双值)构造函数文档,它清楚地说:

Notes: 笔记:

  • The results of this constructor can be somewhat unpredictable. 这个构造函数的结果可能有点不可预测。 One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. 有人可能会假设在Java中编写新的BigDecimal(0.1)会创建一个BigDecimal,它恰好等于0.1(未缩放值为1,标度为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625。 This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). 这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数)。 Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. 因此,传递给构造函数的值并不完全等于0.1,尽管有外观。

  • The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. 另一方面,String构造函数是完全可预测的:写入新的BigDecimal(“0.1”)会创建一个BigDecimal,它正好等于0.1,正如人们所期望的那样。 Therefore, it is generally recommended that the String constructor be used in preference to this one. 因此,通常建议优先使用String构造函数。

So it's better to use the BigDecimal String constructor here: 所以最好在这里使用BigDecimal String构造函数

new BigDecimal("10.12")

This is not a GSON issue. 这不是GSON问题。 new BigDecimal() try to represent double accurately and ends up taking lot more digits. new BigDecimal()尝试准确地表示双重并最终获得更多的数字。

You can use BigDecimal.valueOf(10.12) or new BigDecimal("10.12") instead of new BigDecimal() . 您可以使用BigDecimal.valueOf(10.12)new BigDecimal("10.12")代替new BigDecimal()

System.out.println(GSON.toJson(BigDecimal.valueOf(10.12)));

Instead of relying on the constructor of BigDecimal the best practice is to format it to the desired precision before serializing it with GSON. 而不是依赖于BigDecimal的构造函数,最好的做法是在使用GSON序列化之前将其格式化为所需的精度。

BigDecimal provides a method to convert it to float ( floatValue ) and you can use the String.format(expr, float) function to format it as you wish. BigDecimal提供了一种将其转换为float( floatValue )的方法,您可以使用String.format(expr, float)函数根据需要对其进行格式化。

    BigDecimal value = new BigDecimal(10.12);

    String strValue = String.format("%.2f", value.floatValue());
    System.out.println(GSON.toJson(strValue));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM