java 精度计算 @上源码

本文详细介绍了Java中使用BigDecimal类解决浮点数精度丢失问题的方法,包括字符串构造、四舍五入规则、加减乘除操作以及在金额处理中的应用。通过实例展示了如何避免精度损失,并探讨了不同舍入模式在计算中的选择。
摘要由CSDN通过智能技术生成

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

1.构建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))。

2.四舍五入

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   待完善  感兴趣可以 点赞 收藏 评论 大家一起交流呀

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值