java 精度计算 @上源码

  • Post author:
  • Post category:java


java在进行浮点数运算时,会出现精度丢失问题。未解决精度计算问题,java推出了BigDecimal类。(使用BigDecimal是解决精度计算的一种方案,同时例如支付等业务场景下也可是使用缩小金额单位的方式解决此问题【元转换成分(日元无分哈)】)


构建BigDecimal

BigDecimal bigDecimal = new BigDecimal(1.0001);
BigDecimal bigDecimal = new BigDecimal("1.0001");


BigDecimal 建议使用字符串参数构造的方式(new BigDecimal(String.valueOf(1.0001))),因为如果构造参数本身存在精度问题的情况,转换BigDecimal后进行相应的计算仍然会存在精度丢失的问题new BigDecimal(Double.toString(val))。


四舍五入

BigDecimal bigDecimal = new BigDecimal("1.09401");
// 1.10 ++ 末尾加一
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_UP));  
// 1.09 -- 末尾后直接截取
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_DOWN));    
// 1.10 正数[++ 末尾加一] 负数[-- 末尾后直接截取]
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_CEILING)); 
// 1.09 正数[-- 末尾后直接截取] 负数[++ 末尾加一]
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_FLOOR));       
// 1.09 向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP));     
// 1.09 向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_HALF_DOWN));  
// 1.09 向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 
// ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
// 如果前一位为奇数,则入位,否则舍去。
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_HALF_EVEN));   
                                                                          
                                                                          
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_UNNECESSARY)); // Rounding necessary 断言请求的操作具有精确的结果,因此不需要舍入。
3)加减乘除
BigDecimal bigDecimal1 = new BigDecimal("1.09");
BigDecimal bigDecimal2 = new BigDecimal("2");
BigDecimal bigDecimal3 = BigDecimal.valueOf(2L);
BigDecimal bigDecimal1 = new BigDecimal(1);


// 加 3.09
System.out.println(bigDecimal1.add(bigDecimal2));       
// 减 -0.91
System.out.println(bigDecimal1.subtract(bigDecimal2));  
// 乘 2.18
System.out.println(bigDecimal1.multiply(bigDecimal2));  
// 除 两位小数 向下取值 0.54
System.out.println(bigDecimal1.divide(bigDecimal2, 2 , BigDecimal.ROUND_DOWN)); 
// 除 两位小数 向上取值 0.55
System.out.println(bigDecimal1.divide(bigDecimal2, 2 , BigDecimal.ROUND_UP));


4)金额处理

    public static String longToStringValue(Long price) {
        if (price == null) {
            return "0.00";
        }
        return BigDecimal.valueOf(price).divide(new BigDecimal(100)).toString();
    }

    public static Long stringToLongValue(String price) {
        if (StringUtils.isEmpty(price)) {
            return 0L;
        }
        // 千分位处理
        return new BigDecimal(price.replace(",", "")).multiply(new BigDecimal(100)).longValue();
    }

@浅见 @如有疏漏请帮忙补充完善 @开发一家人  0000014   待完善  感兴趣可以 点赞 收藏 评论 大家一起交流呀



版权声明:本文为qq_34253002原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。