fastjson 处理 double 的精度问题
项目中使用 fastjson 来处理 json 格式,当前使用的版本为1.1.37。在和其它系统交互时,将一个json串传给了对方,原值为5.0,json 处理后格式为:{"dou", 5}; 结果对方处理该串报错了, 原因是他将串整理转成 Map ,在取值时强制转为了 Double ,因为拿到的值转化是 Integer 类型,强转肯定异常了。 简单的做法应该通过 Double.valueOf(value) 进行处理。但无奈合作方不愿意处理。 于是测试了下fastjson处理这个串时,通过以下做处理, 输出的结果为 {"dou", 5}。
JSONObject jsonObject = new JSONObject();
Double dou = new Double(5.0);
jsonObject.put("dou", dou);
System.out.println(JSON.toJSONString(jsonObject));
想要输出{"dou",5.0} 怎么办, 跟踪了下源码,发现在 DoubleSerializer 的 write 方法中,判断了结尾如果是.0 就截掉了。
doubleText = Double.toString(doubleValue);
if(doubleText.endsWith(".0")) {
doubleText = doubleText.substring(0, doubleText.length() - 2);
}
那想要的格式怎么办,可以通过自定义 filter 方式实现,:
ValueFilter filter = new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if(value instanceof BigDecimal || value instanceof Double || value instanceof Float){
return new BigDecimal(value.toString());
}
return value;
}
};
String s = JSON.toJSONString(jsonObject, filter, new SerializerFeature[0]);
以上可以完美解决。后来想有没有跟好的方法呢。 于是网上搜索了一下,大多数都是这种做法,并且有人认为这是一个bug,于是突然想有没有可能 wenshao 会处理一下,于是在 github 找到 fastjson 的最新版本 1.2.23。 先修改 pom 文件,然后运行。发现即使不处理也能输出了 {"dou",5.0} 。 于是 debug 进去原来对 DoubleSerializer 进行了重写,并在 write 方法中原来处理格式的地方修改为如下:
if (decimalFormat == null) {
out.writeDouble(doubleValue, true);
} else {
String doubleText = decimalFormat.format(doubleValue);
out.write(doubleText);
}
//out SerializeWriter
String doubleText = Double.toString(doubleValue);
if (isEnabled(SerializerFeature.WriteNullNumberAsZero) && doubleText.endsWith(".0")) {
doubleText = doubleText.substring(0, doubleText.length() - 2);
}
即,以上粉色代码调用 SerializeWriter 的writeDouble 方法, 看绿色部分。 同时判断了 SerializerFeature.WriteNullNumberAsZero 和 结尾是否为 .0
就是通过这个解决了 double 精度的正常输出。 在使用 1.2.23时如果想输出{"dou", 5}, 可以通过设置 SerializerFeature.WriteNullNumberAsZero 实现。
System.out.println(JSON.toJSONString(jsonObject, SerializerFeature.WriteNullNumberAsZero));
啰嗦了这么,希望通过升级版本解决同样遇到这样问题的小伙伴。
fastjson 处理 double 的精度问题的更多相关文章
- float和double的精度
作者: jillzhang 联系方式:jillzhang@126.com 原网址:http://blog.csdn.net/wuna66320/article/details/1691734 1 范围 ...
- double保持精度,防止小数点后数字的丢失的小方法
一般情况下,输入带小数点的字面值,编译器会把它解析成double 类型. 例如:一个字面值被直接放到代码中,由于带小数点所以,默认值为double类型 输出结果是:1.12345678912345 ...
- float与double的精度和范围
1 范围 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bi ...
- CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作
题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...
- 精确计算java中float和double的精度
[本文相关的代码放在github上.地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式基本遵循IEEE 754标准 ...
- C#中float, double的精度问题
在工作中我发现了一个C#浮点数的精度问题,以下的程序运行结果并未得到我预期的结果: view source print? 01 namespace FloatTest 02 03 class ...
- ceil以及double的精度问题
Codeforces Round #518 (Div. 2) A CF一道水题,总过不去 后面看了一下数据发现是精度出问题了 1000000000000000000 1 1 1000000000000 ...
- float,double等精度丢失问题 float,double内存表示
问题提出:12.0f-11.9f=0.10000038,"减不尽"为什么? 来自MSDN的解释: http://msdn.microsoft.com/zh-cn/c151dt3s. ...
- double发生精度丢失的解决办法
发生精度丢失的原因: 个人理解:机器在运行时,使用2进制形式的计数方式,而我们日常生活中的计算是10进制的,对于整数的加减乘除,double还能适用,但是对于有小数的,则容易发生精度丢失,即用2进制表 ...
随机推荐
- java基础-day16
第05天 API 今日内容介绍 u Object类 & System类 u 日期相关类 u 包装类&正则表达式 第1章 Object类 & System类 1.1 ...
- 二分搜素——(lower_bound and upper_bound)
因为每个人二分的风格不同,所以在学习二分的时候总是被他们的风格搞晕.有的人二分风格是左闭右开也就是[L,R),有的人是左开右闭的(L,R]. 二分的最基本条件是,二分的序列需要有单调性. 下面介绍的时 ...
- ORA-01653: 表 xxxx 无法通过 8192 (在表空间 USERS 中) 扩展
Oracle中增加表空间大小的四种方法 1:给表空间增加数据文件 ALTER TABLESPACE app_data ADD DATAFILE ‘D:\ORACLE\PRODUCT\10.2.0\OR ...
- Spring中ApplicationEvent和ApplicationListener封装
1.测试程序EventTest.java,发布一个事件只需要调用FrameEventHolder.publishEvent()方法即可. package com.junge.spring.event; ...
- RouteOS 频繁自启
本来是一个美好的大周末,突然却被一个突如其来的电话把我从美梦中惊醒,然而一切还不止这么简单...... 本来刚开始了解到信息是客户的一台RouteOS设备挂了,听到这个消息时觉得自己应该可以很 ...
- 13_python_内置函数
- Java代码审计连载之—SQL注入
前言近日闲来无事,快两年都没怎么写代码了,打算写几行代码,做代码审计一年了,每天看代码都好几万行,突然发现自己都不会写代码了,真是很DT.想当初入门代码审计的时候真是非常难,网上几乎找不到什么java ...
- Windows Phone开发手记-WinRT下分组拼音的实现
Windows Phone版本号自升入8.1以来,开发者就多了一个选项,开发基于WinRT架构的WP或者Universal Windows App.然而开发框架转为WinRT后,很多原有的WP8基于S ...
- [原创]K8正方系统密码解密工具
工具: K8_zfsoftDecode编译: 自己查壳组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8.blog.163.com发布: 2015/8/1 1 ...
- JS数组去重的几种常见方法
JS数组去重的几种常见方法 一.简单的去重方法 // 最简单数组去重法 /* * 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中 * IE8以下不支持数组的indexOf方法 * */ ...