java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式)

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));

结果:
java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式)_第1张图片

使用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));

结果:
java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式)_第2张图片

        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));

结果
java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式)_第3张图片

使用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));

结果:
java中float、double和BigDecimal的精度问题(fastjson、Jackson以及实例化的方式)_第4张图片

解决方案:

在需要使用高精度数据时,需要使用String作为入参,才能保证json数据的准确。

你可能感兴趣的:(后端学习,java,json)