【本文参考《Java核心技术 卷1 第十版》】
如果基本的整数和浮点数精度不能满足需求,那么可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数据序列的数值。BigInteger类实现类任意精度的整数运算,BigDecimal实现类任意精度的浮点数运算。
一、BigInteger
使用静态的valueOf()方法可以将普通的数值转换为大数值。如:
public class BigValueTest {
public static void main(String[] args) {
int i = 100;
BigInteger bigInteger = BigInteger.valueOf(i);
System.out.println(bigInteger);//输入100
}
}
遗憾的是,使用大数值运算时,不能使用人们熟悉的算术运算符(如 + ,- ,* ,/),而需要使用大数值类中的方法。常用的API如下:
.BigInteger add(BigInteger other)//加法
.BigInteger substract(BigInteger other) //减法
. BigInteger multiply(BigInteger other) //乘法
.BigInteger divide(BigInteger other) //除法
. BigInteger mod(BigInteger other) //取余
int compareTo(BigInteger other) //比较,如果等于other,返回0;如果小于other,返回负数;如果大于other,返回正数。
.static BigInteger valueOf(long x) //把x转换为BigInteger类型
代码如下:
public static void main(String[] args) {
long l = 100L;
//long类型转换为BigInteger
BigInteger bi_1 = BigInteger.valueOf(l);
//加法
BigInteger add = bi_1.add(BigInteger.valueOf(200L));
System.out.println("相加运算 add = " + add); //300
//减法
BigInteger subtract = add.subtract(BigInteger.valueOf(50));
System.out.println("相减运算 subtract = " + subtract); // 250
//乘法
BigInteger multiply = subtract.multiply(BigInteger.valueOf(2));
System.out.println("相乘运算 multiply = " + multiply);//500
//除法
BigInteger divide = multiply.divide(BigInteger.valueOf(5));
System.out.println("相除运算 divide = " + divide);//100
//取余
BigInteger mod = divide.mod(BigInteger.valueOf(3));
System.out.println("取余运算 mod = " + mod);
//比较运算
int i = add.compareTo(subtract);
System.out.println("add 与 subtract 比较运算,结果是:" + i);
}
二、BigDecimal
实现类任意精度的浮点数运算,常用api如下:
BigDecimal add(BigDecimal other) ;//加法
BigDecimal substract(BigDecimal other) ;//减法
BigDecimal multiply(BigDecimal other) ;//乘法
BigDecimal divide(BigDecimal other,RoundingMode mode) ;//除法
int compareTo(BigDecimal other) //比较,如果等于other,返回0;如果小于other,返回负数;如果大于other,返回正数。
.static BigDecimal valueOf(long x) //把x转换为BigInteger类型
public static void main(String[] args) {
long l = 100L;
BigDecimal b1 = BigDecimal.valueOf(l);
BigDecimal b2 = new BigDecimal("2.5");
BigDecimal b3 = new BigDecimal("2.6");
//加法
BigDecimal add = b2.add(b3);
System.out.println("2.5 + 2.6 = " + add); //5.1
//减法
BigDecimal subtract = add.subtract(new BigDecimal("1.5"));
System.out.println("5.1 - 1.5 = " + subtract);//3.6
//乘法
BigDecimal multiply = subtract.multiply(new BigDecimal("2.1"));
System.out.println("3.6 * 2.1 = " + multiply); // 7.56
//除法
BigDecimal divide = multiply.divide(new BigDecimal("2.3"), RoundingMode.HALF_UP);
System.out.println("7.56 / 2.3 = " + divide); //3.29
//比较
int i = divide.compareTo(multiply);
System.out.println("3.29 与 7.56 比较结果是:" + i); // -1
}
补充:
BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;
除法 divide有三个参数的方法,第一参数表示除数,第二个参数表示小数点后保留位数,第三个参数表示取舍规则。只有在作除法运算或四舍五入时才用到取舍规则。 因为BigDecimal除法可能出现不能整除的情况,比如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。所以当我们用三参数的除法方法时,规定了保留几位小数以及你的保留方式,就可以避免异常。
ROUND_CEILING:舍位时往正无穷方向移动
正数:1.1 -> 2 1.5-> 2 1.8-> 2
负数:-1.1-> -1 -1.5-> -1 -1.8-> -1
ROUND_DOWN:向0的方向移动
正数:1.1-> 1 1.5-> 1 1.8-> 1
负数:-1.1-> -1 -1.5-> -1 -1.8> -1
ROUND_FLOOR:与CEILING相反,往负无穷
正数: 1.1-> 1 1.5-> 1 1.8-> 1
负数: -1.1-> -2 -1.5-> -2 -1.8-> -2
ROUND_HALF_DOWN:以5为分界线,或曰五舍六入
正数:1.5-> 1 1.6-> 2
负数:-1.5-> -1 -1.6-> -2
ROUND_HALF_EVEN:同样以5为分界线,如果是5,则前一位变偶数
1.15-> 1.2 1.16-> 1.2 1.25-> 1.2 1.26-> 1.3
ROUND_HALF_UP:最常见的四舍五入
ROUND_UNNECESSARY:无需舍位
ROUND_UP与ROUND_DOWN相反,远离0的方向
正数:1.1-> 2 1.5-> 2 1.8-> 2
负数:-1.1-> -2 -1.5-> -2 -1.8-> -2