BigDecimal 类学习
要点:
标题BigDecimal 类主要是通过精度(precision)及规模(scale)来确定数值,其中精度是没有缩放前的数值,规模是缩小放大的一个指数。官方公式为:(unscaledValue × 10^-scale),如一个BigDecimal类型的数据的精度为100,scale为2那么这个数据就是——1.00。
BigDecimal 要求程序员必须为除不尽的小数,或者缩放时导致的数据的舍入指定一个数据舍入的方法。数据的舍入方法有如下7种方法+1种不舍入
以下例子,全部要求保留两位小数
RoundingMode.CEILING:向上取舍
0.666 ---->0.67
0.660 ---->0.66
-0.666 ----->-0.66
RoundingMode.FLOOR :向下取舍
0.666 ---->0.66
0.660 ---->0.66
-0.666 ----->-0.67
RoundingMode.UP:向远离0的方向取舍
0.666 ---->0.67
0.660 ---->0.66
-0.666 ----->-0.67
RoundingMode.DOWN :向靠近0 的方向取舍
0.666 ---->0.66
0.660 ---->0.66
-0.666 ----->-0.66
RoundingMode.HALF_UP:四舍五入
0.666 ---->0.67
0.660 ---->0.66
-0.666 ----->-0.67
RoundingMode.HALF_DOWN:五舍六入
0.666 ---->0.67
0.660 ---->0.66
-0.666 ----->-0.67
RoundingMode.HALF_EVEN:五舍六入,被舍位数值为5的时候前一位为奇数+1变成偶数,前一位为偶数的时候直接舍去最后一位即可
0.665 ---->0.66
0.655 ----->0.66
0.660 ---->0.66
-0.665 ----->-0.66
RoundingMode.UNNECESSARY:不需要舍入,完整的展示整个数据,不适用与无线小数,因为无线小数必须舍入才可以显示
一、构造器
BigDecimal可以将所有数值类型的基本数据类型 及 数值型字符串 转为BigDecimal类型数据;
- var bd = new BigDecimal(String value);//转字符串为数值,不存在精度丢失问题
- var bd = new BigDecimal(int value);//转int整数为BigDecimal数值,不存在精度丢失问题
- var bd = new BigDecimal(long value);//转long整数为BigDecimal数据,不存在精度丢失问题
- var bd = new BigDecimal(byte value);//转byte整数为BigDecimal数据,不存在精度丢失问题
- var bd = new BigDecimal(short value);//转short整数为BigDecimal数据,不存在精度丢失问题
- var bd = new BigDecimal(char value);//转char代表的整数为BigDecimal数据,不存在精度丢失问题
- var bd = new BigDecimal(floor value);//转floor整数为BigDecimal数据,存在精度丢失问题
- var bd = new BigDecimal(double value);//转floor整数为BigDecimal数据,存在精度丢失问题
- var bd = new BigDecimal(char[] arr);//将数组的数值拼接成BigDecimal数据,如有字符数组{‘1’,‘2’,‘3’},将会返回123;
- var bd = new BigDecimal(char[] arr ,int index ,int length);//从某个角标开始截取一定长度的字符组合,而后拼接,如 有字符数组{‘1’,‘2’,‘3’}
var bd = new BigDecimal(arr ,0 ,3),将会返回123;
小结
对于整数类型的数据直接转没有精度丢失的问题,但是对于浮点类型数据会有丢失问题,应该先将浮点类型数据转为String数据,而后调用形参为String的构造方法。
BigDecimal.valueOf()
本方法非构造方法,为静态方法,只可以传入double | float类型的数据, 这个方法不会造成精度丢失问题。
二、数据的加减乘除等数学运算
bdX为BigDecimal类型数据的实例
①加法:bd1.add(bd2);//bd1+bd2
②减法:bd1.subtract(bd2);//bd1-bd2
③乘法:bd1.multply(bd2);//bd1bd2
④除法:bd1.divide(bd2,int scale ,Roundingmode r);//bd1/bd2,对于特殊的除不尽小数必须指定规模,及四舍五入方法
⑤取余:bd1.remainder(bd2);//bd1%bd2
⑥幂运算:bd1.pow(int i);//bd1^i
⑦扩大10的n次方倍:bd1.scaleByPowerOfTen(int i);//bd110^i3,结果以科学计数法表述
⑧取商:bd1.divideToIntergerValue(bd2);//61/5=12
⑨取大值:bd1.max(bd2)//返回二者较大者
⑩取小值:bd1.min(bd2)//返回二者较小者
⑩取相反数:bd1.negate();
⑩取自身:bd1.plus();
三、小数点移动
①左移:bd1.movePointLeft(int i);//bd1=100,i=1,则返回10.0
②右移:bd1.movePointRight(int i );//bd1=100,i=1,则返回1000
四、数据修剪
①bd1.setScale(int scale , RoundingMode r);//如bd1=123.456,bd1.setScale(2,RoundingMode.HALF_UP)—>123.46
五、数据类型转化
①转为int, bd1.intValue
②转为long, bd2.longValue
③转为byte, bd3.byteValue
④转为short, bd4.shortValue
⑤转为double bd5.doubleValue
⑥转为float bd6.floatValue
⑦转为String bd7.toString//可能返回科学记数类型的字符串
bd9.toPlainString()//这个方法不会返回科学记数类型的字符串
六、数据的精度和规模
①bd1.scale();//返回此数据的规模(小数点后几位)如0.10—>2
②bd2.precision();//返回此数据的精度的位数,如0.102–>3
七、equals和compareTo的区别
①equals返回布尔值 ,compareTo返回-1 0 1(对应<=>)
②equals只要数值在数学上是相等的就认为是相等的,如2==2.0;
compareTo则必须要精度和规模都相等才认为相等,2!=2.0