大数字类型目的是为了破除基本类型因为精度限制而存在表达范围的藩篱。
其分别是用于表达超大整数(任意大小,无数值范围限制)的大整数类型(BigInteger)和能够表达许多位小数的大小数类型(BigDecimal)。
1.大整数BigInteger
import java.math.BigInteger;
首先,对于初始化则不像基本类型包装这块讲着3种方式,这里只剩下valueOf() 可以对其初始化。
接着,大整数变量不能使用算术运算符,需要通过以下方法进行运算:
- add():取代了加法运算符“+”;
- subtract():取代了减法运算符“-”;
- multiply():取代了乘法运算符“*”;
- divide():取代了除法运算符“/”;
- remainder():取代了取余运算符“%”;
- negate():取代了负号运算符“-”。
【代码】
......
BigInteger nine = BigInteger.valueOf(9); // 生成一个指定数值的大整数变量
BigInteger four = BigInteger.valueOf(4); // 生成一个指定数值的大整数变量
BigInteger sum = nine.add(four); // add方法用来替代加法运算符“+”
System.out.println("sum="+sum);
BigInteger sub = nine.subtract(four); // subtract方法用来替代减法运算符“-”
System.out.println("sub="+sub);
BigInteger mul = nine.multiply(four); // multiply方法用来替代乘法运算符“*”
System.out.println("mul="+mul);
BigInteger div = nine.divide(four); // divide方法用来替代除法运算符“/”
System.out.println("div="+div);
BigInteger remainder = nine.remainder(four); // remainder方法用来替代取余数运算符“%”
System.out.println("remainder="+remainder);
BigInteger neg = nine.negate(); // negate方法用来替代负号运算符“-”
System.out.println("neg="+neg);
再次,Java虽提供Math数学函数库,但此函数库只适用于操作基本数字类型变量。因而BigInteger另外提供了 abs方法 和 pow方法 。
【代码】
......
BigInteger abs = nine.abs(); // abs方法用来替代数学库函数Math.abs
System.out.println("abs="+abs);
BigInteger pow = nine.pow(2); // pow方法用来替代数学库函数Math.pow
System.out.println("pow="+pow);
2.大小数BigDecimal
import java.math.BigDecimal;
大小数的初始化和相关运算都与大整数的保持一致,应用方式都是一样的。
但有一点易错:如果使用divide方法求出来的结果为无限循环小数,则程序会异常退出,那如何解决这样的问题呢?
除法运算的divide方法需要3个输入参数:除数、需保留的小数位数、多余数字的舍入规则 。
BigDecimal提供的数字舍入规则如下:
-
ROUND_CEILING:往数值较小的方向取整,类似于Math库的ceiling函数。
-
ROUND_FLOOR:往数值较大的方向取整,类似于Math库的floor函数。
-
ROUND_HALF_UP:四舍五入取整,若多余的数字等于.5,则前一位进1,类似于Math库的round函数。
-
ROUND_HALF_DOWN:类似四舍五入取整,区别在于:若多余的数字等于.5,则直接舍弃。
【注】通常情况下四舍五入会采取:RoundingMode.HALF_UP (impot java.math.RoundingMode;)
- ROUND_HALF_EVEN:如果保留位数的末尾为奇数,则按照ROUND_HALF_UP方式取整。如果保留位数的末尾为偶数,则按照ROUND_HALF_DOWN方式取整。
【代码】
......
BigDecimal one = BigDecimal.valueOf(100);
BigDecimal three = BigDecimal.valueOf(3);
// 大小数的除法运算,小数点后面保留64位,其中最后一位做四舍五入
BigDecimal div = one.divide(three, 64, BigDecimal.ROUND_HALF_UP);
System.out.println("div="+div);
为了减少后面两个精度参数反复调用改动,Java又提供了精度工具 MathContext ,即事先指定包含小数精度和舍入规则在内的精度规则。
import java.math.MathContext;
【优化代码】
// 利用工具MathContext,可以把divide方法的输入参数减少为两个(优化)
MathContext mc = new MathContext(64, RoundingMode.HALF_UP); //RoundingMode.HALF_UP 通常代表四舍五入
BigDecimal divByMC = one.divide(three, mc); // 根据指定的精度规则执行除法运算
System.out.println("divByMC="+divByMC);
在大小数的除法中引入精度工具MathContext至少有以下两个好处:
- 精度规则只要定义一次,即可多处使用;
- 若要变更精度规则,则只需要修改一个地方。