Java 常用类库之 BigDecimal
完整名java.math.BigDecimal
提供不可变的,任意精度的带符号十进制数。一个BigDecimal有一个任意精度的整型非缩放值unscaledValue和一个 32 位整型缩放值scale组成。scale就是用于指定unscaledValue的缩放量级,scale >= 0时,它表示小数点右边的位数,scale < 0时,它表示当前BigDecimal对象对应的数值为unscaledValue*10^(-scale)。
BigDecimal类提供了算术,缩放操作,舍入,比较,散列和格式转换的操作。 toString()方法提供了一个BigDecimal的规范表示 。 由于BigDecimal对象是可变的,所以每次算数操作都返回一个新的BigDecimal对象表示运算结果。
BigDecimal提供了表示数字 0、1 和 10 的三个整数常量。
public static final BigDecimal ZERO = ZERO_THROUGH_TEN[0];
public static final BigDecimal ONE = ZERO_THROUGH_TEN[1];
public static final BigDecimal TEN = ZERO_THROUGH_TEN[10];
这里的ZERO_THROUGH_TEN数组保存了整数 0-10 对应的所有 BigDecimal对象。
BigDecimal原本提供了针对舍入操作的一系列常量,如ROUND_HALF_EVEN等,但在 Java 9 之后被弃用,使用 RoundingMode.HALF_EVEN等枚举值表示同样的作用。
-
构造方法
BigDecimal()BigDecimal的构造方法根据接收的数据种类可以分为三类:字符类型的、数字类型和BigInteger类型。- 接收字符类型的构造器包括接收字符数组
char[]和字符串String。
// [0] 调用构造器 [1] public BigDecimal(char[] in, int offset, int len) { this(in,offset,len,MathContext.UNLIMITED); } // [1] public BigDecimal(char[] in, int offset, int len, MathContext mc) {} // 调用构造器 [0] public BigDecimal(char[] in) { this(in, 0, in.length); } // 调用构造器 [1] public BigDecimal(char[] in, MathContext mc) { this(in, 0, in.length, mc); } // 调用构造器 [0] public BigDecimal(String val) { this(val.toCharArray(), 0, val.length()); } // 调用构造器 [1] public BigDecimal(String val, MathContext mc) { this(val.toCharArray(), 0, val.length(), mc); }从源码中可以看出,真正起作用的构造器就是构造器 [1],其它几个构造器都是通过直接或者间接地调用它来实现的。所以这里只需要明白构造器 [1] 的参数意义就可以了。参数
in必须是一个可以表示某个数字的字符数组(可以包含e,表示科学计数,但也需要在有意义的位置),否则程序会产生异常NumberFormatException;offset和len指定观察的范围,offset表示从in中观察的第一个位置,len表示需要观察的长度即字符个数;mc是一个MathContext对象,用于指定以怎样的精度以及舍入方式生成BigDecimal表示的值。举一个例子:char[] num = {'1', '3', '.', '1' ,'4', '1', '5', '9', '2'}; BigDecimal val = new BigDecimal(num, 1, 6, new MathContext(4, RoundingMode.HALF_EVEN)); System.out.println(val); /* output: 3.142 */这里表示以
num数组的'3'到'5'部分生成BigDecimal对象,MathContext对象指定的精度为 4(表示保留 4 个有效数字),使用RoundingMode.HALF_EVEN的舍入方式。- 接收数字类型的构造器包括接收
double/int/long三种基本数据类型。
public BigDecimal(double val) { this(val,MathContext.UNLIMITED); } public BigDecimal(double val, MathContext mc) {} public BigDecimal(int val) {} public BigDecimal(int val, MathContext mc) {} public BigDecimal(long val) {} public BigDecimal(long val, MathContext mc) {}- 接收
BigInteger对象的构造器
public BigDecimal(BigInteger val) {} public BigDecimal(BigInteger val, MathContext mc) {} public BigDecimal(BigInteger unscaledVal, int scale) {} public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {}BigInteger是一个与BigDecimal类似的不可变的表示整数的对象。构造器中的参数scale指定量级为 -scale。在看一个例子就知道了:BigInteger num = new BigInteger("12345"); BigDecimal val2 = new BigDecimal(num, 2); System.out.println(val2); /* output: 123.45 */ - 接收字符类型的构造器包括接收字符数组
-
valueOf()该方法提供了一个直接从数据类型生成
BigDecimal对象的方式,使用方式是直接传入需要转换的基本数据类型,支持long/double两种基本数据类型。public static BigDecimal valueOf(long unscaledVal, int scale) {} public static BigDecimal valueOf(long val) {} public static BigDecimal valueOf(double val) {} -
add()public BigDecimal add(BigDecimal augend) {} // mc 用于指定结果的精度与舍入方式 public BigDecimal add(BigDecimal augend, MathContext mc) {}使用
add()对当前BigDecimal对象this跟另一个BigDecimal对象参数augend作加法操作,对应于数值上的this + augend,返回结果为一个新的BigDecimal对象。 -
subtract()public BigDecimal subtract(BigDecimal subtrahend) {} public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {}使用
subtract()对当前BigDecimal对象this跟另一个BigDecimal对象参数subtrahend作减法操作,对应于数值上的this - subtrahend,返回结果为一个新的BigDecimal对象。 -
multiply()public BigDecimal multiply(BigDecimal multiplicand) {} public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {}使用
multiply()对当前BigDecimal对象this跟另一个BigDecimal对象参数multiplicand作减法操作,对应于数值上的this * subtrahend,返回结果为一个新的BigDecimal对象。 -
divide()// 可以指定结果的缩放量级 scale 和舍入方式 RoundingMode public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {} public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {} public BigDecimal divide(BigDecimal divisor) {} public BigDecimal divide(BigDecimal divisor, MathContext mc) {}使用
divide()对当前BigDecimal对象this跟另一个BigDecimal对象参数divisor作减法操作,对应于数值上的this / divisor,返回结果为一个新的BigDecimal对象。 -
divideToIntegralValue()public BigDecimal divideToIntegralValue(BigDecimal divisor) {} public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {}同样作除法操作,但返回所得商值的整数部分。
-
remainder()public BigDecimal remainder(BigDecimal divisor) {} public BigDecimal remainder(BigDecimal divisor, MathContext mc) {}使用
remainder()对当前BigDecimal对象this跟另一个BigDecimal对象参数divisor作取余操作,对应于数值上的this % divisor,返回结果为一个新的BigDecimal对象。 -
divideAndRemainder()public BigDecimal[] divideAndRemainder(BigDecimal divisor) {} public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {}相当于同时进行了
divideToIntegralValue()和remainder()两个操作,返回一个BigDecimal数组,包含两个元素,第一个是divideToIntegralValue()的结果,第二个是remainder()的结果。注意,如果有同时得到整数商和余数的需求,使用该方法比分别使用
divideToIntegralValue()和remainder()两个方法要快,因为它的内部只做了一次除法。 -
pow()public BigDecimal pow(int n) {} public BigDecimal pow(int n, MathContext mc) {}求幂操作,求
this对应值的 n 次方,返回结果为一个新的BigDecimal对象。 -
abs()public BigDecimal abs() {} public BigDecimal abs(MathContext mc) {}求绝对值,即求
|this|。 -
negate()public BigDecimal negate() {} public BigDecimal negate(MathContext mc) {}反转操作,即求
-this。 -
plus()public BigDecimal plus() { return this; } public BigDecimal plus(MathContext mc) {}返回当前
BigDecimal的对象值,即+this。它的存在是为了和negate()方法保持对称性。 -
signum()public int signum() {}返回当前
BigDecimal表示数值的符号。返回 -1 代表负数,0 代表零,1 代表正数。 -
scale()public int scale() { return scale; }返回当前
BigDecimal对象的scale值。scale值的作用已经在开头说明。 -
percision()public int precision() {}返回当前
BigDecimal的精度,即有效位数。 -
unscaledValue()public BigInteger unscaledValue() {}返回一个
BigInteger对象(假设为unscaledValue),其对应的值为当前BigDecimal的非缩放值,即是this * 10^(this.scale())。 -
round()public BigDecimal round(MathContext mc) {}根据参数
mc指定的精度返回一个近似值的BigDecimal对象。 -
setScale()public BigDecimal setScale(int newScale, RoundingMode roundingMode) {} public BigDecimal setScale(int newScale) {}设置缩放量级。
setScale()主要用于对BigDecimal数据小数点后的位数进行进位、舍位、截断等操作。 -
movePointLeft()和movePointRight()public BigDecimal movePointLeft(int n) {} public BigDecimal movePointRight(int n) {}前者左移小数点,后者右移小数点,返回移动小数点后的一个新
BigDecimal对象。 -
scaleByPowerOfTen()public BigDecimal scaleByPowerOfTen(int n) {}在原数上乘以 10 的 n 次方,返回新的
BigDecimal对象。 -
stripTrailingZeros()public BigDecimal stripTrailingZeros() {}返回一个
BigDecimal对象,其对应的数值等于原对象数值,但移除了尾部零。比如对于值为 600.0 的BigDecimal,其 [BigInteger,scale] 组成为 [6000, 1],那么通过该方法得到的BigDecimal其值为 6e2,对应的 [BigInteger,scale] 组成为 [6, -2]。如果该BigDecimal在数值上等于零,则方法返回BigDecimal.ZERO。 -
compareTo()public int compareTo(BigDecimal val) {}比较当前
BigDecimal值和val对象值,返回 -1、0 或 1,分别代表当前BigDecimal值小于、等于或小于val值。对于两个值相同而 scale 值不同的BigDecimal对象,比如其值为 2.0 和 2.00,该方法判定为两者相等。 -
equals()public boolean equals(Object x) {}判断当前
BigDecimal对象于所给参数对象x是否相等。与compareTo()不同,equals()要求只有两个BigDecimal的 value 值和 scale 值都相等时,才判定两者相等(所以 2.0 和 2.00 是不相等的)。 -
min()和max()public BigDecimal min(BigDecimal val) {} public BigDecimal max(BigDecimal val) {}前者返回当前
BigDecimal对象和val之间的最小值,后者返回两者之间的最大值。 -
hashCode()返回当前对象的哈希码(2.0 和 2.00 的哈希码是不同的)。
-
toString()、toEngineeringString()和toPlainString()public String toString() {} public String toEngineeringString() { public String toPlainString() {}toString()以字符串形式返回当前BigDecimal对象表示的数值,必要时会使用科学计数法。toEngineeringString()基本上和toString()返回同样的结果。不同的地方在于当返回的结果为科学计数法的形式时。toPlainString()不会返回科学计数法的形式。看一个例子吧:BigDecimal val = new BigDecimal(new BigInteger("123456"), -9); System.out.println(val); System.out.println(val.toEngineeringString()); System.out.println(val.toPlainString()); /* output: 1.23456E+14 123.456E+12 123456000000000 */toEngineeringString()在输出为科学计数法时,会让 10 的指数为 3 的倍数,这样表示出的整数部分就处于 1 到 999 之间。 -
toBigInteger()和toBigIntegerExact()public BigInteger toBigInteger() {} public BigInteger toBigIntegerExact() {}两者都是将当前的
BigDecimal转换得到一个BigInteger对象。前者在转换中会丢掉原数的小鼠部分,所以可能有信息损失;后者不允许信息损失,所以当原数存在非零小数部分时,会直接抛出异常ArithmeticException。 -
lnogValue()和longValueExact()public long longValue(){} public long longValueExact() {}两者都时将当前
BigDecimal转换得到一个long型整数。前者类似于基本收缩转换(arrowing primitive conversion),即去掉小数部分,并且当整数部分的BIgInteger值超出long型数据范围时,取其低 64 位,因此可能有信息损失;后者不允许信息损失,所以当遇到非零小数部分或者整数部分超限时,直接抛出异常ArithmeticException。 -
shorValueExact()和byteValueExact()public short shortValueExact() {} public byte byteValueExact() {}作用和
longValueExact()类似,只是分别转换得到short型和1byte型数据。都不允许信息丢失。 -
floatValue()和doubleValue()public float floatValue(){} public double doubleValue(){}转换当前
BigDecimal对象值得到浮点型数据,转换允许信息损失。 -
ulp()public BigDecimal ulp() {}返回当前
BigDecimal的最后位置单位大小(ulp)。实际上它的值为 [1,this.scale()],即1*10^(-this.scale())。
以下是从 Java 9 开始加入的方法:
-
sqrt()public BigDecimal sqrt(MathContext mc) {}开平方操作,返回结果为一个新的
BigDecimal对象。

浙公网安备 33010602011771号