BigDecimal用法及注意事项

BigDecimal用法及注意事项

前言

查看compareTo源码发现并无异常处理机制,在使用CompareTo方法时一定要对入参进行判空处理异常处理

比较大小:

if(a.compareTo(b) == -1){
    System.out.println("a小于b");
}
 
if(a.compareTo(b) == 0){
    System.out.println("a等于b");
}
 
if(a.compareTo(b) == 1){
    System.out.println("a大于b");
}
 
if(a.compareTo(b) > -1){
    System.out.println("a大于等于b");
}
 
if(a.compareTo(b) < 1){
    System.out.println("a小于等于b");
}

基础运算:

//加减乘除:
 
BigDecimal a= new BigDecimal("10");  
BigDecimal b= new BigDecimal("5");  
  
//加法  
 a.add(b);       
 
  
//减法  
 a.subtract(b);  
 
  
//乘法  
 a.multiply(b);  
 
  
//除法  
 a.divide(b);  
 
 
setScale(2) // 表示保留两位小数,默认用四舍五入方式 
setScale(2,BigDecimal.ROUND_DOWN) // 向下取整
setScale(2,BigDecimal.ROUND_UP)   // 向上取整
setScale(2,BigDecimal.ROUND_HALF_UP) // 四舍五入
setScaler(2,BigDecimal.ROUND_HALF_DOWN) // 四舍五入,如果是5则向下舍

常见错误:

1、BigDecial的所有操作都会生成一个新的对象:

amount.add( thisAmount ); // 错误
amount = amount.add( thisAmount ); // 正确

2、不要用equals方法来比较BigDecimal对象,因为它的equals方法会比较scale,如果scale不一样,它会返回false;

例如:
BigDecimal a = new BigDecimal(“1.00”);
BigDecimal b = new BigDecimal(“1.0”);
print(a.equals(b)); // false

BigDecimal bigDecimal = new BigDecimal(“0.0”);
System.out.println(bigDecimal.equals(BigDecimal.ZERO));// false

3、如果直接使用a.divide(b)除法,有时会报除不尽异常,如下:

BigDecimal a = new BigDecimal(10);
BigDecimal b = new BigDecimal(3);
a = a.divide(b); // 错误会报如下异常:java.lang.ArithmeticException: Non-terminating
decimal expansion; no exact representable decimal result.

demo工具类案例:

package com.lyj.demo.utils;

import com.lyj.demo.constant.Constants;
import com.lyj.demo.constant.GlobalConstant;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author 凌兮
 * @date 2020/7/28 11:17
 * BigDecimal工具类
 * setScale(scale, BigDecimal.ROUND_HALF_UP)
 *
 * setScale()方法用于格式化小数点
 *
 * scale 精度(保留几位小数)
 *
 * ROUND_HALF_UP 四舍五入
 *
 * 需要使用double,要注意:
 *
 * 1、请使用 BigDecimal.valueOf(amount) 进行转换,不能直接new BigDecimal(amount),这样会出现精度问题。
 *
 * 2、以double入参,以double精度为准。
 *
 *
setScale(2) // 表示保留两位小数,默认用四舍五入方式
setScale(2,BigDecimal.ROUND_DOWN) // 向下取整
setScale(2,BigDecimal.ROUND_UP)   // 向上取整
setScale(2,BigDecimal.ROUND_HALF_UP) // 四舍五入
setScaler(2,BigDecimal.ROUND_HALF_DOWN) // 四舍五入,如果是5则向下舍
 */
public final class BigDecimalUtil {

    /**
     * 四舍五入保留两位小数
     *
     * @param bigDecimal
     * @return
     */
    public static String scale2(BigDecimal bigDecimal) {
        return ObjectUtils.isEmpty(bigDecimal) ? GlobalConstant.ZERO : bigDecimal.setScale(Constants.TWO, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 原样输出不采用默认的toString以科学计数法输出
     *
     * @param bigDecimal
     * @return 币值字符串
     */
    public static String toString(BigDecimal bigDecimal) {
        return ObjectUtils.isEmpty(bigDecimal) ? GlobalConstant.ZERO : bigDecimal.toPlainString();
    }

    /**
     * 两数相加
     *
     * @param value1
     * @param value2
     * @return
     */
    public static BigDecimal add(BigDecimal value1, BigDecimal value2) {
        return value1.add(value2);
    }

    /**
     * 分转元(除以100)(支持大数16位以上)保留两位小数
     *
     * @param amount 分金额
     * @return 元金额
     */
    public static String changeF2Y(String amount) {
        return new BigDecimal(amount).divide(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 元转分(乘以100)(支持大数16位以上)
     *
     * @param amount 元金额
     * @return 分金额
     */
    public static String changeY2F(String amount) {
        return new BigDecimal(amount).multiply(new BigDecimal("100")).toString();
    }

    /** ---------------------compareTo源码发现并无异常处理机制,所以a,b都不可为空,异常需提前处理-------------*/
    /**
     * amount 是否等于0
     *
     * @param amount 金额
     * @return 0:等于0,-1:小于0,1:大于0
     */
    public static int equalToZero(BigDecimal amount) {
        // 判空并抛异常信息
       Objects.requireNonNull(amount,"param amount is null");
        return amount.compareTo(BigDecimal.ZERO);
    }

    /**
     * A与B的大小比较
     *
     * @param a 金额A
     * @param b 金额B
     * @return 0:相等,-1:a<b,1:a>b
     */
    public static int aCompareToB(BigDecimal a, BigDecimal b) {
        Objects.requireNonNull(a, "param a is null");
        Objects.requireNonNull(b, "param b is null");
        return a.compareTo(b);
    }

    /**
     * double类型
     * @param amount
     * @return
     */
    public static String changeF2Y(double amount){
        return BigDecimal.valueOf(amount).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }


    /**
     * 货币测试
     * @param args
     */
    public static void main(String[] args) {

        //普通数值
        System.out.println(changeF2Y("101"));
        //1.01
        System.out.println(changeY2F("101"));
        //10100
        System.out.println(changeF2Y(23.45));
        // 0.23

        //超16位以上数值
        System.out.println(changeF2Y("34353452345768679845234534343445"));
        //343534523457686798452345343434.45
        System.out.println(changeY2F("32123134757697845454423534232323"));
        //3212313475769784545442353423232300
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌兮~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值