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
对象。
以上是 Java 常用类库之 BigDecimal 的全部内容, 来源链接: utcz.com/z/392589.html