如果基本类型 long / double 不能满足整数和浮点数运算的 精度要求, 则可以使用 java.math 包 下的 BigInteger / BigDecimal 工具类, 实现任何精度的运算;
使用 BigInteger 实现了任意精度的整型运算
使用 BigDecimal 实现了任意精度的浮点型运算
1. 基本用法与常用方法
/*
* 以 BigInteger 为例 (BigDecimal 方法与 BigInteger 相同)
*/
public static void main(String[] args) {
// 1. 构造实例:
// 两种方法: 通过静态方法 valueOf() 和 new Instance 方法
BigInteger bi = BigInteger.valueOf(3_123_456_789L);
BigInteger bi2 = new BigInteger("2333333333333333");
// BigInteger(byte[])
// BigInteger(int[])
// BigInteger(int, byte[])
// BigInteger(int, int[])
// BigInteger(String, int)
// BigInteger(char[], int, int)
// 2. add / sub / multiply / divide / mod
// 在 BigInteger 和 BigDecimal 中, 没有算数运算符, 只能通过实例方法进行运算
// 注意: 在使用实例方法运算的时候, 如: 使用 bi.add(bi2), 不会改变 bi 和 bi2 的值;
System.out.println(bi.add(bi2));;
System.out.println(bi.subtract(bi2));
System.out.println(bi.multiply(bi2));
System.out.println(bi.divide(bi2));
System.out.println(bi.mod(bi2));
}
2. 源码分析
2.1 BigInteger 源码
/**
* Immutable arbitrary-precision (任意精度) integers. All operations behave as if
* BigIntegers were represented in two's-complement notation (like Java's
* primitive integer types). BigInteger provides analogues(类似物, 这里指的是实例方法,
* 如: add() / substract() 方法, 替代 + / - 运算符) to all of Java's
* primitive integer operators, and all relevant methods from java.lang.Math.
* Additionally, BigInteger provides operations for modular arithmetic, GCD
* calculation, primality testing, prime generation, bit manipulation,
* and a few other miscellaneous operations.
*
* @see BigDecimal
* @since JDK1.1
*/
public class BigInteger extends Number implements Comparable<BigInteger> {
/**
* The signum of this BigInteger: -1 for negative, 0 for zero, or
* 1 for positive. Note that the BigInteger zero <i>must</i> have
* a signum of 0. This is necessary to ensures that there is exactly one
* representation for each BigInteger value.
*
* @serial
*/
final int signum;
/**
* The magnitude of this BigInteger, in <i>big-endian</i> order: the
* zeroth element of this array is the most-significant int of the
* magnitude. The magnitude must be "minimal" in that the most-significant
* int ({@code mag[0]}) must be non-zero. This is necessary to
* ensure that there is exactly one representation for each BigInteger
* value. Note that this implies that the BigInteger zero has a
* zero-length mag array.
*/
final int[] mag;
/**
* Translates a byte array containing the two's-complement binary
* representation of a BigInteger into a BigInteger. The input array is
* assumed to be in <i>big-endian</i> byte-order: the most significant
* byte is in the zeroth element.
*
* @param val big-endian two's-complement binary representation of
* BigInteger.
* @throws NumberFormatException {@code val} is zero bytes long.
*/
public BigInteger(byte[] val) {
// ...
}
/**
* This private constructor translates an int array containing the
* two's-complement binary representation of a BigInteger into a
* BigInteger. The input array is assumed to be in <i>big-endian</i>
* int-order: the most significant int is in the zeroth element.
*/
private BigInteger(int[] val) {
//...
}
/**
* Translates the sign-magnitude representation of a BigInteger into a
* BigInteger. The sign is represented as an integer signum value: -1 for
* negative, 0 for zero, or 1 for positive. The magnitude is a byte array
* in <i>big-endian</i> byte-order: the most significant byte is in the
* zeroth element. A zero-length magnitude array is permissible, and will
* result in a BigInteger value of 0, whether signum is -1, 0 or 1.
*
* @param signum signum of the number (-1 for negative, 0 for zero, 1
* for positive).
* @param magnitude big-endian binary representation of the magnitude of
* the number.
* @throws NumberFormatException {@code signum} is not one of the three
* legal values (-1, 0, and 1), or {@code signum} is 0 and
* {@code magnitude} contains one or more non-zero bytes.
*/
public BigInteger(int signum, byte[] magnitude) {
//...
}
/**
* A constructor for internal use that translates the sign-magnitude
* representation of a BigInteger into a BigInteger. It checks the