java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式):
问题描述
java中如果使用float或double类型的数据初始化BigDecimal的话,会出现精度问题,这是因为BigDecimal的构造方法只能保证String类型的数据在初始化的时候是正确的数值,同理,由于Fastjson和Jackson在进行将java类型转化为Json类型时,同样会出现精度问题:
new BigDecimal的方式:
使用new BigDecimal的方式将float或者double类型初始化为BigDecimal会出现精度问题
···
float exampleFloat = 9999999999999999.99f;
double exampleDouble = 9999999999999999.99;
String exampleString = "9999999999999999.99";
System.out.println("float to BigDecimal :" + new BigDecimal(exampleFloat));
System.out.println("double to BigDecimal :" + new BigDecimal(exampleDouble));
System.out.println("String to BigDecimal :" + new BigDecimal(exampleString));
结果:
使用Jackson的convertValue方法:
使用Jackson的convertValue方法会出现精度问题
···
float exampleFloat = 9999999999999999.99f;
double exampleDouble = 9999999999999999.99;
String exampleString = "9999999999999999.99";
ObjectMapper jacksonObjectMapper = new ObjectMapper();
System.out.println("float to json(jackson) :" + jacksonObjectMapper.convertValue(exampleFloat,String.class));
System.out.println("double to json(jackson) :" + jacksonObjectMapper.convertValue(exampleDouble,String.class));
System.out.println("String to json(jackson) :" + jacksonObjectMapper.convertValue(exampleString,String.class));
结果:
float exampleFloat = 9999999999999999.99f;
double exampleDouble = 9999999999999999.99;
String exampleString = "9999999999999999.99";
ObjectMapper jacksonObjectMapper = new ObjectMapper();
System.out.println("float to json(jackson) :" + jacksonObjectMapper.convertValue(exampleFloat,BigDecimal.class));
System.out.println("double to json(jackson) :" + jacksonObjectMapper.convertValue(exampleDouble,BigDecimal.class));
System.out.println("String to json(jackson) :" + jacksonObjectMapper.convertValue(exampleString,BigDecimal.class));
结果
使用Fastjson的JSONObject.toJSONString方法:
使用new BigDecimal的方式将float或者double类型初始化为BigDecimal会出现精度问题
···
float exampleFloat = 9999999999999999.99f;
double exampleDouble = 9999999999999999.99;
String exampleString = "9999999999999999.99";
System.out.println("float to json(fastjson) :" + JSONObject.toJSONString(exampleFloat));
System.out.println("double to json(fastjson) :" + JSONObject.toJSONString(exampleDouble));
System.out.println("String to json(fastjson) :" + JSONObject.toJSONString(exampleString));
结果:
解决方案:
在需要使用高精度数据时,需要使用String作为入参,才能保证json数据的准确。