BigInteger

在Java中,由CPU原生提供的整型最大范围是64位long型整数。使用long型数据可以直接通过CPU指令进行计算,速度非常快。
如果我们使用的整数范围超过了long,那么我们就只能使用软件模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:

import java.math.BigInteger;

public class Main {
    public static void main(String[] args) {
        BigInteger big = new BigInteger("123456789");
        System.out.println(big.pow(5));
    }
}

输出:
28679718602997181072337614380936720482949

BigInteger做运算时,只能使用实例方法,常用的运算方法如下:

  • 加法:BigInteger add(BigInteger val)返回两个大整数的和
  • 减法:BigInteger subtract(BigInteger val)返回两个大整数相减的结果
  • 乘法:BigInteger multiply(BigInteger val)返回两个大整数的乘积
  • 除法:BigInteger divide(BigInteger val)返回两个大整数的商
  • 取模:BigInteger mod(BigInteger val)用当前大整数对val取模
  • 求相反数:BigInteger negate()返回当前大整数的相反数
  • 幂运算:BigInteger pow(int exponent)返回当前大整数的exponent次方

数值转换方法如下:

  • 转换为bytebyteValue()
  • 转换为shortshortValue()
  • 转换为intintValue()
  • 转换为longlongValue()
  • 转换为floatfloatValue()
  • 转换为doubledoubleValue() 通过上述方法,可以把BigInteger转换为基本类型。但是,如果BigInteger表示的范围超过了基本数据范围,转换时将丢失高位信息,即结果不一定是准确的。如果需要准确的转换成基本数据类型,可以使用intValueExact()longValueExact等方法,在转换时如果超出范围,将直接抛出ArithmeticException异常。

BigDecimal

和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。

构造方法:

  • BigDecimal(String val):将String类型转换成BigDecimal类型
  • BigDecimal(double val):将double类型转换成BigDecimal类型
  • BigDecimal(int val):将int类型转换成BigDecimal类型
  • BigDecimal(long val):将long类型转换成BigDecimal类型

数值转换

  • 转换成StringtoString()
  • 转换成doubledoubleValue()
  • 转换成floatfloatValue()
  • 转换成longlongValue()
  • 转换成intintValue()

运算方法:

  • 加法:BigDecimal add(BigDecimal val)返回两个BigDecimal的和;
  • 减法:BigDecimal subtract(BigDecimal val)返回两个BigDecimal的差;
  • 乘法:BigDecimal multiply(BigDecimal val)返回两个BigDecimal的乘积;
  • 除法:BigDecimal divide(BigDecimal divisor)返回两个BigDecimal的商;
  • 取模:BigDecimal remainder(BigDecimal divisor)返回两个BigDecimal的和;
  • 最大数: BigDecimal max(BigDecimal val)返回两个BigDecimal的最大值;
  • 最小数:BigDecimal min(BigDecimal val)返回两个BigDecimal的最小值;
  • 绝对值:BigDecimal abs()返回BigDecimal的绝对值;
  • 相反数:BigDecimal negate()返回BigDecimal的相反数;

其中除法运算较为特殊:

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

可以看出,除法divide有三个参数的方法,第一参数divisor表示除数,第二参数scale表示小数点后保留位数,第三个参数表示取舍规则。只有在作除法运算或者四舍五入时才用到取舍规则。
取舍规则如下:

ROUND_CEILING //向正无穷方向舍入
ROUND_DOWN //向零方向舍入
ROUND_FLOOR //向负无穷方向舍入
ROUND_HALF_DOWN  //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN  //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_HALF_UP  //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式
ROUND_UP //向远离0的方向舍入

我们最常用的四舍五入是ROUND_HALF_UP

四舍五入
setScale(,int scale, int roundingMode) 第一个参数表示小数点后保留位数,第二个参数表示取舍规则,最常用的四舍五入是HALF_UP

比较BigDecimal
可以使用equals()方法,但是要求两个Bigdecimal的值相等,并且要求他们的位数scale()相等。比如:

BigDecimal a = new BigDecimal("123.32000");
BigDecimal b = new BigDecimal("123.32");
System.out.println(a.equals(b));  //   false

必须使用compareTo()方法来比较,它会根据两个值的大小分别返回负数、正数和0,分别代表小于、大于和等于。

BigDecimal a = new BigDecimal("123.32000");
BigDecimal b = new BigDecimal("123.32");
System.out.println(a.compareTo(b));  //   0

其他方法:

  • stripTrailingZeros():可以将一个BigDecimal格式化为一个相等的但是去掉了末尾0的BigDecimal
  • scale():表示小数位数,如果为负数,比如-2,表示这个数是整数,且末尾有2个0。