BigInteger和BigDecimal类位于math包,BigInteger可以进行超过Integer范围内的数据进行运算,而BigDecimal能精确的表示、计算浮点数,常用在金融领域。
1 BigInteger类
public class BigInteger extends Number
implements Comparable
位于java.math包,可以对超过Integer范围内的数据进行运算。
1.1 构造函数和常用方法
/* 构造函数*/
/**
* 将十进制字符串表示的整数形式转换为 BigInteger,该类同样是不可变的。
*
* @param val
*/
public BigInteger(String val)
/* 常用方法*/
//加
public BigInteger add(BigInteger val)
//减
public BigInteger subtract(BigInteger val)
//乘
public BigInteger multiply(BigInteger val)
//除
public BigInteger divide(BigInteger val)
//返回商和余数的数组
public BigInteger[] divideAndRemainder(BigInteger val)
1.2 案例
BigInteger bi1 = new BigInteger("100");
BigInteger bi2 = new BigInteger("3");
//加
System.out.println(bi1.add(bi2));
//减
System.out.println(bi1.subtract(bi2));
//乘
System.out.println(bi1.multiply(bi2));
//除,bi1/bi2
System.out.println(bi1.divide(bi2));
//取模,bi1%bi2
System.out.println(bi1.remainder(bi2));
//返回除和取模的结果的数组
BigInteger[] bi = bi1.divideAndRemainder(bi2);
//0索引是bi1/bi2
System.out.println(bi[0]);
//1索引是bi1%bi2
System.out.println(bi[1]);
2 BigDecimal类
错误案例
@Test
public void test3()
{
System.out.println(0.09 + 0.01); //0.09999999999999999
System.out.println(1.0 - 0.32); //0.6799999999999999
System.out.println(1.015 * 100); //101.49999999999999
System.out.println(1.301 / 100); //0.013009999999999999
}
以上结果出现如此情况。是因为在运算的过程中,float类型和double类型可能引起精度的丢失。
由于在运算的时候,float类型和double很容易丢失精度。所以,为了能精确的表示、计算浮点数,特别是针对金融领域,Java提供了BigDecimal类。
public class BigDecimal extends Number implements
Comparable
位于java.math包。BigDecimal表示不可变的、任意精度的有符号十进制数,可以解决浮点型数据运算数据丢失问题。以后在金融行业可能会使用到该类!
2.1 构造函数和常用方法
/*构造函数*/
/**
* 将 BigDecimal 的字符串表示形式转换为 BigDecimal。
*
* @param val BigDecimal 的字符串表示形式
*/
public BigDecimal(String val)
/*方法*/
//加
public BigDecimal add(BigDecimal augend)
//减
public BigDecimal subtract(BigDecimal subtrahend)
//乘
public BigDecimal multiply(BigDecimal multiplicand)
// 除
public BigDecimal divide(BigDecimal divisor)
/**
* 由于divide是精确计算,因此出现无限小数时,会报错:
* java.lang.ArithmeticException:Non-terminating decimal expansion;no exact representable decimal result
* 解决的办法就是给divide方法设置精确的小数点,采用下面的方法。
*
* @param divisor 除数
* @param scale 保留几位小数,不够加0
* @param roundingMode 要应用的舍入模式。其字段中具有规定。其中,四舍五入字段:ROUND_HALF_UP。也可以用4代替
* @return
*/
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
舍入模式介绍
- ROUND_UP:向远离零的方向舍入。舍弃非零部分,并将非零舍弃部分相邻的一位数字加一。
- ROUND_DOWN:向接近零的方向舍入。舍弃非零部分,同时不会非零舍弃部分相邻的一位数字加一,采取截取行为。
- ROUND_CEILING:向正无穷的方向舍入。如果为正数,舍入结果同ROUND_UP一致;如果为负数,舍入结果同ROUND_DOWN一致。注意:此模式不会减少数值大小。
- ROUND_FLOOR:向负无穷的方向舍入。如果为正数,舍入结果同ROUND_DOWN一致;如果为负数,舍入结果同ROUND_UP一致。注意:此模式不会增加数值大小。
- ROUND_HALF_UP:“四舍五入”。
- ROUND_HALF_DOWN:“五舍六入”。
- ROUND_HALF_EVEN:向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则相邻的偶数舍入。如果舍弃部分左边的数字奇数,则舍入行为与
ROUND_HALF_UP相同;如果为偶数,则舍入行为与
ROUND_HALF_DOWN相同。注意:在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况,如果前一位为奇数,则入位,否则舍去。- ROUND_UNNECESSARY:断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
2.2 案例
BigDecimal bd1 = new BigDecimal("0.09");
BigDecimal bd2 = new BigDecimal("0.01");
//add:0.10
System.out.println("add:" + bd1.add(bd2));
BigDecimal bd3 = new BigDecimal("1.0");
BigDecimal bd4 = new BigDecimal("0.32");
//subtract:0.68
System.out.println("subtract:" + bd3.subtract(bd4));
BigDecimal bd5 = new BigDecimal("1.015");
BigDecimal bd6 = new BigDecimal("100");
//multiply:101.500
System.out.println("multiply:" + bd5.multiply(bd6));
BigDecimal bd7 = new BigDecimal("1.301");
BigDecimal bd8 = new BigDecimal("100");
//divide:0.01301
System.out.println("divide:" + bd7.divide(bd8));
BigDecimal bd9 = new BigDecimal("1.301");
BigDecimal bd10 = new BigDecimal("100");
//divide:0.0130100
System.out.println("divide:" + bd7.divide(bd8, 7, BigDecimal.ROUND_UP));