BigDecimal加减乘除计算,取整,BigDecimal保留两位小数并且四舍五入,及注意事项

前言:

        在项目中碰到一个打折的问题,例如用户在页面输入0.66,表示打6.6折,在数据库中是用float类型的字段保存的,保存的是0.66,然后数据库的float类型对应了java的一个double类型,后端需要把0.66取出来,然后乘以10,显示6.6折传给前端,但是在java里面,double类型的0.66乘以10,并不等于6.6,而是6.6000000000000005
 

cc84d2f67e4e4ef585481d967273e6aa.png

       

查询了一下百度,才知道是精度损失的问题,所以就需要使用BigDecimal来进行计算



        到后面才发现,有涉及到小数点的一定要使用 decimal 类型,别想着使用flaot或者double类型可以省点字节长度,因为不管使用的是double类型或者float类型的话,对应到java的都是double类型的属性,而在java中使用double类型会出现各种精度丢失的情况,比如定义1.30的一个值,使用System.out.println输出就会出现精度丢失的情况,更别说要参与各种加减乘除的运算了,而且使用double的时候,会自动把最后的一个0去掉,所以在项目中使用double,会造成各种的不便

初始化:

        BigDecimal bigDecimal = new BigDecimal("3.00");

b254b6b2396745e79c82182f600a5d65.png

         BigDecima类在初始化的时候,官方是建议直接使用字符串来作为参数进行实例化的

重点:

         BigDecimal bigDecimalA = new BigDecimal("0.39");

         BigDecimal bigDecimalB = new BigDecimal("0.3");

        这两个在初始化的时候,虽然只是小数点后面的位数不一样,但是这个区别,在做乘法的时候就能很容易看出区别来。
        bigDecimalA的小数点后面有两位,只要在做乘法的时候,最后两位如果不是0,那就会自动补0。例如 0.39 * 10 是39 ,但是在创建bigDecimalA对象的时候,是有小数点两位数的,然后会自动补00,所以算出来是39.00,例如0.39 *10 是3.9,现在小数点只有一位,然后就会再补一个0,所以算出来是3.90,再例如0.39 * 2 是0.78 现在算出来的结果已经有两位小数了,所以就不会再补0了


        BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。

计算:

public BigDecimal add(BigDecimal value);                           //加法
public BigDecimal subtract(BigDecimal value);                   //减法 
public BigDecimal multiply(BigDecimal value);                    //乘法
public BigDecimal divide(BigDecimal value);                       //除法


除法,保留两位小数

countSum.divide(a,2, RoundingMode.HALF_UP);

除法之后取整数:

BigDecimal b1 = new BigDecimal("1256");
BigDecimal b2 = new BigDecimal("1000");
//四舍五入保留两位小数
BigDecimal b3=b1.divide(b2,2,BigDecimal.ROUND_HALF_UP); //输出:1.26
//向上取整
BigDecimal b4=b1.divide(b2,BigDecimal.ROUND_UP); //输出:2
//向下取整
BigDecimal b5=b1.divide(b2,BigDecimal.ROUND_DOWN); //输出:1
//保留两位小数向上取整
BigDecimal b6=b1.divide(b2,2,BigDecimal.ROUND_UP); //输出:1.26

直接取整:

BigDecimal b7 = new BigDecimal("12.51");
//保留一位小数向上取整
BigDecimal b8=b7.setScale( 1, BigDecimal.ROUND_UP); //输出 12.6
// 按照整数位向上取整
b7.setScale(0,BigDecimal.ROUND_UP); //输出 13
// 向下取整
b7.setScale(0,BigDecimal.ROUND_DOWN); //输出 12

BigDecimal四舍五入后保留两位小数

BigDecimal.getPrice().setScale(2, RoundingMode.HALF_UP)
或者
BigDecimal.getPrice().setScale(2, 4)
也可以使用这个方法来设置不够两位小数的时候,自动补0:

ff5c8e2f47c44c0c882ee15e0fe15050.png
 

猜你喜欢

转载自blog.csdn.net/qq_26112725/article/details/130211224