BigDecimal
用于解决浮点型运算时,出现结果失真的问题
BigDecimal常见构造器及方法
构造器 | 说明 |
---|---|
public BigDecimal(double val) (不推荐) | 将double转换为BigDecimal |
public BigDecimal(String val) | 把String转换成BigDecimal |
方法名 | 说明 |
---|---|
public static BigDecimal valueOf(double val) | 转换一个double成BigDecimal |
public BigDecimal add(BigDecimal b) | 加法 |
public BigDecimal subtract(BigDecimal b) | 减法 |
public BigDecimal multiply(BigDecimal b) | 乘法 |
public BigDecimal divide(BigDecimal b) | 除法 |
public BigDecimal divide(另一个BigDecimal对象, 精确几位, 舍入模式) | 除法,可以控制精确到小数几位 |
public double doubleValue() | 将BigDecimal转换为double |
案例演示
public class BigDecimalTest {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
System.out.println(a + b); //0.30000000000000004 结果失真
System.out.println("-----------------------------");
//将0.1和0.2转换成字符串封装成BigDecimal对象来运算
// BigDecimal a1 = new BigDecimal(Double.toString(a));
// BigDecimal b1 = new BigDecimal(Double.toString(b));
//优化,前两行代码已经被封装到valueOf()方法里
BigDecimal a1 = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
//加法
System.out.println(a1.add(b1)); //0.3
//减法
System.out.println(b1.subtract(a1)); //0.1
//乘法
System.out.println(a1.multiply(b1)); //0.02
//除法
System.out.println(b1.divide(a1)); //2
BigDecimal c1 = BigDecimal.valueOf(0.3);
BigDecimal d1 = BigDecimal.valueOf(0.1);
// System.out.println(d1.divide(c1)); //异常:Non-terminating decimal expansion(无法精确表达结果,1无法除尽3,需保留精度)
//public BigDecimal divide(另一个BigDecimal对象, 精确几位, 舍入模式)
System.out.println(d1.divide(c1, 10, RoundingMode.HALF_UP));
//public double doubleValue() 将BigDecimal对象转换成double类型
double db = d1.doubleValue();
System.out.println(d1);
}
}
补充:BigDecimal中的8种舍入模式
BigDecimal类提供了多种舍入模式,这些模式定义在RoundingMode枚举类中
舍入模式 | 说明 |
---|---|
UP | 不论舍弃部分的数值是多少(除非是0),始终将数字舍入到远离零的方向 |
DOWN | 将数字舍入到接近零的方向,即直接截断超出精度的尾数部分,不进行四舍五入 |
CEILING | 向正无穷大方向舍入 |
FLOOR | 向负无穷大方向舍入 |
HALF_UP | 通常理解的“四舍五入”,如果舍弃部分 >= 5,则向远离零的方向舍入;否则,舍入到最近的偶数(银行家舍入法) |
HALF_DOWN | 如果舍弃部分 > 5,则向远离零的方向舍入;否则,向零方向舍入 |
HALF_EVEN | 舍入模式向“最近邻”舍入,除非两个邻域都是等距的,在这种情况下,向偶数邻舍入。如果舍弃部分正好为5,则舍入到与前一位数字同奇偶性的数字 |
UNNECESSARY | 如果舍弃部分非零,则抛出 ArithmeticException 异常,表示不允许舍去非零部分。此模式只用于不需要舍入的情况,确保计算精确无舍入误差。 |
案例演示
public class RoundingModeTest {
public static void main(String[] args) {
//ROUND_UP
BigDecimal up1 = new BigDecimal("123.789");
//public BigDecimal setScale(int newScale, RoundingMode roundingMode)
//用于设置或改变该 BigDecimal 对象的精度(小数点后的位数),同时根据指定的舍入模式进行数值的调整。
//newScale: 整型值,表示要设定的精度。例如,如果设置为2,则结果将保留两位小数。
//roundingMode 舍入模式
up1 = up1.setScale(2, RoundingMode.UP);
System.out.println(up1); //123.79
BigDecimal up2 = new BigDecimal("123.331");
System.out.println(up2.setScale(2, RoundingMode.UP)); //123.34
//ROUND_DOWN
System.out.println("--------------------------------");
BigDecimal down1 = new BigDecimal("123.456");
System.out.println(down1.setScale(2, RoundingMode.DOWN)); //123.45
//ROUND_CEILING
System.out.println("---------------------------------");
BigDecimal cei1 = new BigDecimal("110.353");
System.out.println(cei1.setScale(2, RoundingMode.CEILING)); //110.36
//ROUND_FLOOR
System.out.println("---------------------------------");
BigDecimal fl1 = new BigDecimal("99.847");
System.out.println(fl1.setScale(2, RoundingMode.FLOOR)); //99.84
//ROUND_HALF_UP
System.out.println("---------------------------------");
BigDecimal hu1 = new BigDecimal("144.987");
System.out.println(hu1.setScale(2, RoundingMode.HALF_UP)); //144.99
BigDecimal hu2 = new BigDecimal("144.984");
System.out.println(hu2.setScale(2, RoundingMode.HALF_UP)); //144.98
//ROUND_HALF_DOWN
System.out.println("---------------------------------");
BigDecimal hd1 = new BigDecimal("88.655");
System.out.println(hd1.setScale(2, RoundingMode.HALF_DOWN)); //88.65
BigDecimal hd2 = new BigDecimal("88.656");
System.out.println(hd2.setScale(2, RoundingMode.HALF_DOWN)); //88.66
BigDecimal hd3 = new BigDecimal("88.657");
System.out.println(hd3.setScale(2, RoundingMode.HALF_DOWN)); //88.66
//ROUND_HALF_EVEN
System.out.println("---------------------------------");
BigDecimal he1 = new BigDecimal("655.347");
System.out.println(he1.setScale(2, RoundingMode.HALF_EVEN)); //655.35
BigDecimal he2 = new BigDecimal("655.344");
System.out.println(he2.setScale(2, RoundingMode.HALF_EVEN)); //655.34
BigDecimal he3 = new BigDecimal("655.345");
System.out.println(he3.setScale(2, RoundingMode.HALF_EVEN)); //655.34
//ROUND_UNNECESSARY
System.out.println("---------------------------------");
BigDecimal un1 = new BigDecimal("133.455");
try {
System.out.println(un1.setScale(2, RoundingMode.UNNECESSARY));
} catch (ArithmeticException e) { //因为舍去部分非零,所以抛出ArithmeticException
System.out.println(e.getMessage());
}
BigDecimal un2 = new BigDecimal("133.450");
System.out.println(un2.setScale(2, RoundingMode.UNNECESSARY)); //133.45
}
}