先看遇到的问题:
package lesson2; public class Demo05 { public static void main(String[] args) { double d1 = 1.0; double d2 = 0.9; System.out.println(d1-d2);
//面试题 double result = (1.4-0.5)/0.9; System.out.println(result); } }
为什么会出现上面的情况呢?
简单点说就是,计算机在存储浮点数字时以二进制方法存储,在进行转化为二进制时存储的小数部分出现部分数据丢失,而成为近似值,从而导致在计算时出现错误。
详细可参考:Java中浮点数运算不准确的原因
为解决此类问题而引入BigDecimal类
BigDecimal类的构造方法挺多的,但这里只介绍一种public BigDecimal(String val)
,将字符串表示形式转换为BigDecimal。注意这里一定是字符串String,如果在参数为小数时,使用double类型时,会出现一定的问题(注意看实例)。
BigDecimal创建的是对象,所以在运算的时候不能再使用+-*/
等算术运算符进行直接运算,而是使用相应的方法。
方法 | 描述 |
---|---|
public BigDecimal add(BigDecimal augend) | 加法 |
public BigDecimal subtract(BigDecimal subtrahend) | 减法 |
public BigDecimal multiply(BigDecimal multiplicand) | 乘法 |
public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode) | 除法。divisor - 此 BigDecimal 要除以的值。scale - 要返回的 BigDecimal 商的标度。roundingMode - 要应用的舍入模式。 |
这里需要注意的是,在进行除法运算时,如果结果为除不尽的数,未标明保留几位小数(或使用舍入的方式),会抛出的异常:
常用的四舍五入的方法:
常量 | 描述 |
---|---|
ROUND_HALF_UP | 四舍五入 |
ROUND_UP | 直接进位 |
ROUND_DOWN | 直接舍弃 |
ROUND_HALF_DOWN | 舍弃部分>0.5进位,否则舍弃 |
package lesson2;
import java.math.BigDecimal;
public class Demo05 {
public static void main(String[] args) {
//BigDecimal,大的浮点数
System.out.println("======减法======");
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
BigDecimal r1=bd1.subtract(bd2);
System.out.println(r1);
System.out.println("=====加法=====");
BigDecimal r2=bd1.add(bd2);
System.out.println(r2);
System.out.println("======乘法======");
BigDecimal r3=bd1.multiply(bd2);
System.out.println(r3);
System.out.println("======除法======");
BigDecimal r4 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(r4);
BigDecimal r5 = new BigDecimal("10").divide(new BigDecimal("3"),2,BigDecimal.ROUND_HALF_UP);
//10除以3的结果四舍五入,保留两位小数
System.out.println(r5);
}
}