BigDecimal由任意精度的整数非标度值和32位的整数标度(scale)组成。
如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以10的负scale次幂。
因此,BigDecimal表示的数值是(unscaledValue×10-scale)。
一、BigDecimal的创建:
// 第一种用new一个对象的方式
BigDecimal b1 = new BigDecimal("0.48");
// 第二种用内部方法获取
BigDecimal b2 = BigDecimal.valueOf(0.48);
注意使用new BigDecimal创建时一般都用String对象作为参数,如果是float或者dubbo会丢失精度
例如:BigDecimal b1 = new BigDecimal(0.1);可能会变为0.099999999999...所以要用new BigDecimal("0.1")要传String
二、BigDecimal的加减乘除
public BigDecimal add(BigDecimal value);//加法
public BigDecimal subtract(BigDecimal value);//减法
public BigDecimal multiply(BigDecimal value);//乘法
public BigDecimal divide(BigDecimal value);//除法
注意:例如如下
BigDecimal a = new BigDecimal(10);
BigDecimal b = new BigDecimal(3);
//出现无限循环小数时,会抛异常的。
BigDecimal c = a.divide(b);
应该使用如下:
//四舍五入,取两位小数。这里对除不尽的数更多的处理详见源码。
BigDecimal d = a.divide(b,2,BigDecimal.ROUND_HALF_EVEN);这样就不会出异常
三、BigDecimal的加减乘除进行运算以后都是返回了一个新的BigDecimal而不是在原有的对象上增加的因此:
BigDecimal b1 = BigDecimal.ZERO;
BigDecimal b2 = BigDecimal.valueOf(3);
b2 = b2.add(b1); // 这样写的话会把新的对象赋值个b2
b2.add(b1); // 这样的话b2是不会变化的
四、BigDecimal比较
BigDecimal是通过使用compareTo(BigDecimal)来比较的,具体比较情况如下:
BigDecimal a = new BigDecimal("1");
BigDecimal b = new BigDecimal("2");
BigDecimal c = new BigDecimal("1");
int result1 = a.compareTo(b);
int result2 = a.compareTo(c);
即左边比右边数大,返回1,相等返回0,比右边小返回-1。 注意不能使用equals方法来比较大小。
五、BigDecimal格式化保留位数:
1. BigDecimal num1 = new BigDecimal(2.225667);//这种写法不允许,会造成精度损失一般都用String.value(2.225667)作为参数
setScale用来获取保留位数
BigDecimal decimal = new BigDecimal("1.12345").setScale(4,BigDecimal.ROUND_HALF_DOWN);//保留四位向上取整
BigDecimal setScale = decimal.setScale(2,BigDecimal.ROUND_HALF_DOWN);//保留两位
BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN);//2.22 直接去掉多余的位数
BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP);//2.23 跟上面相反,进位处理
ROUND_CEILING 天花板(向上),正数进位向上,负数舍位向上
ROUND_HALF_UP
BigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP);//2.23 四舍五入(若舍弃部分>=.5,就进位)
BigDecimal.setScale()方法用于格式化小数点
setScale(1)表示保留一位小数,默认用四舍五入方式
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍
我们经常要将数字进行格式化,比如取2位小数,这是最常见的。Java 提供DecimalFormat类,df.format返回String帮你用最快的速度将数字格式化为你需要的样子。下面是一个例子:
DecimalFormat df = new DecimalFormat("#.##");//舍弃多余部分只取两位
df.format(bigDital对象)
//每三位以逗号进行分隔。
System.out.println(new DecimalFormat(",###").format(c)); //299,792,458
//将格式嵌入文本
System.out.println(new DecimalFormat("光速大小为每秒,###米。").format(c));
//以百分比方式计数,并取两位小数
System.out.println(new DecimalFormat("#.##%").format(pi)); //314.16%