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

本文探讨了Java中使用float和double类型初始化BigDecimal时出现的精度问题,以及Fastjson和Jackson在转换为JSON时的精度问题。示例展示了直接使用newBigDecimal和转换方法导致的不精确结果。解决方案建议在需要高精度时使用String类型作为参数。
摘要由CSDN通过智能技术生成

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数据的准确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值