【Java】BigDecimal类的使用
问题引入: 浮点数运算存在一定的问题
System.out.println(0.1 + 0.2); //0.30000000000000004
System.out.println(0.09 + 0.01); //0.09999999999999999
因此用BigDecimal类对浮点数的"运算"使用
BigDecimal导包操作
由于BigDecimal类不属于java.lang包下,因此需要导入包
import java.math.BigDecimal;
BigDecimal的创建/初始化
建议使用两种方式,以防止精度损失
-
对字符串的构造方法进行调用
BigDecimal bd = new BigDecimal("3.2"); BigDecimal bd = new BigDecimal(0.1+"");
请注意,不要在里面构造方法中进行直接运算
BigDecimal bd = new BigDecimal(0.1 + 0.2 + ""); System.out.println(bd); //0.30000000000000004
原因:
我们使用BigDecimal类,是防止运算出现问题。而0.1 + 0.2是相当于两个double类型的数先运算后再进行了,再将结果转化成BigDecimal对象。
-
使用BigDecimal类提供的静态方法valueOf()
BigDecimal bd = BigDecimal.valueOf(12.5); int a = 1810; BigDecimal bd = BigDecimal.valueOf(a);
听说这样比较优雅
BigDecimal类用来运算的方法
她进行的运算是绝对精准的,并且不会保留格外多的位数
首先,来两个要运算的数
int a = 10;
int b = 3;
BigDecimal a1 = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
-
加
System.out.println( a1.add(b1) ); //13
-
减
System.out.println( a1.subtract(b1) ); //7
-
乘
System.out.println( a1.multiply(b1) ); //30
-
除
System.out.println( a1.divide(b1) ); //报异常
我们上面提过,BigDecimal进行的运算是绝对精确的,可是呢,10/3是一个无线循环的小数。那么这个运算对她来说就是很难为情的。
正确的用法可以这样:
import java.math.RoundingMode; // 使用到了RoundingMode.HALF_UP System.out.println( a1.divide(b1, 2, RoundingMode.HALF_UP) ); //3.33
各个参数的对应含义是
被除数.divide(除数, 保留到小数点后几位(可以取0,真的取整了就), 使用什么样"某位取整(在要保留的位数与后面的一位进行考虑)"方式)
RoundingMode.HALF_UP 是 四舍五入,也就是>=0.5就进一
RoundingMode.HALF_DOWN 是 >5 才进一
RoundingMode.UP 是 后面有数就丢弃后面,进一
RoundingMode.DOWN 是 截断操作,丢弃后面的数
RoundingMode.CEILING 是 如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同 。即向上取整
列如: -2.4 -> -2 2.4 -> 3
RoundingMode.FLOOR 是 如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同。即向下取整
例如: -2.4 -> -3 2.4 -> 2
-
主动进行进位运算
import java.math.RoundingMode; double c = 6.6666; BigDecimal c1 = BigDecimal.valueOf(c); System.out.println(c1.setScale(0, RoundingMode.FLOOR)); //6 保留到个位,向下取整
各个参数的对应含义是
取舍数.setScale(精度位, 取整方式)
与divid方法的后两个参数对应含义相同。
数据的保留
我们开始强调BigDecimal类的作用是运算。但是我们一般使用并不是用BigDecimal进行的。要将她转成基本数据类型。
当然,可以直接进行输出,是没问题的。
int a = 10;
BigDecimal a1 = BigDecimal.valueOf(a);
System.out.println( a1 ); //10
**原因:**重写了toString( ) 方法。
如果只是运算了一个中间值,要进行后续运算,除了都转换成BigDecimal类进行运算,还可以把她转回去
使用:
intValue() 和 doubleValue() 方法
BigDecimal bd = new BigDecimal("18.6");
int a = bd.intValue(); //18
double b = bd.doubleValue(); //18.6
使用:
intValue() 和 doubleValue() 方法
BigDecimal bd = new BigDecimal("18.6");
int a = bd.intValue(); //18
double b = bd.doubleValue(); //18.6
提醒
本文,部分思路和案例参考B站:黑马程序员 的 视频 。主要由自己凭感觉和参考API来写。部分理解和用词只是自己觉得好理解就使用了。并且实验代码运行结果,均有自己测试而出,测试jdk 版本我也不太清楚怎么看,所以请自己进行测试确定正确性。最后但是很重要的,欢迎各位指正,感谢。