BigDecimal用法详解及其四舍五入问题
一、简介
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。二、构造器描述
BigDecimal(int) 创建一个具有参数所指定整数值的对象。BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
三、方法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。
四.下面我写一个工具类方便大家理解
public class CaculateBigDecimal {
/**
* @param addOne
* @param addTwo
* @return 高精度的加法运算
*/
public static double bigDecimalAdd(double addOne ,double addTwo){
//创建BigDecimal对象
BigDecimal b1=new BigDecimal(addOne);
BigDecimal b2=new BigDecimal(addTwo);
return b1.add(b2).doubleValue();
}
/**
* @param subOne
* @param subTwo
* @return 高精度运算减法
*/
public static double bigDecimalSub(double subOne,double subTwo){
BigDecimal b1=new BigDecimal(subOne);
BigDecimal b2=new BigDecimal(subTwo);
return b1.subtract(b2).doubleValue();
}
/**
* @param mulOne
* @param mulTwo
* @return 高精度的乘法
*/
public static double bigDecimalMul(double mulOne,double mulTwo){
BigDecimal b1=new BigDecimal(mulOne);
BigDecimal b2=new BigDecimal(mulTwo);
return b1.multiply(b2).doubleValue();
}
/**
* @param divOne
* @param divTwo
* @return 高精度除法
*/
public static double bigDecimalDiv(double divOne,double divTwo){
BigDecimal b1=new BigDecimal(divOne);
BigDecimal b2=new BigDecimal(divTwo);
return b1.divide(b2).doubleValue();//这里可以设置保留精度,保留位数下面我们在细细介绍。
}
/**
* @param roundDate
* @param length 保留小数后的位数
* @return 返回四舍五入后的参数
*/
public static double bigDecimalRound(double roundDate,int length){
BigDecimal b1=new BigDecimal(roundDate);
BigDecimal b2=new BigDecimal(1);
//第三个参数是表示四舍五入操作,这里传入的参数需要时字符串,不然可能不对下面我在介绍。
return b1.divide(b2, length, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* @param roundDate
* @param length
* @return 返回四舍五入后的参数
*/
public static double bigDecimalStringRound(String roundDate,int length){
BigDecimal b1=new BigDecimal(roundDate);
BigDecimal b2=new BigDecimal(1);
return b1.divide(b2, length, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
五.常见问题及其相关介绍
public BigDecimal(double val)将 double 转换为 BigDecimal,后者是 double 的二进制浮点值准确的十进制表示
形式。返回的 BigDecimal 的标度是使 (10scale × val) 为整数的最小值。
注:
此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正
好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于
0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为
double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入 到构造方法的值不会正好等于
0.1(虽然表面上等于该值)。
另一方面,String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好 等于
预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。
当 double 必须用作 BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结
果:先使用 Double.toString(double) 方法,然后使用 BigDecimal(String) 构造方法,将 double 转换为 String。要获
取该结果,请使用 static valueOf(double) 方法。
六.四舍五入的配置参数介绍
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则向下舍
注释:
1:scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");
b.scale(),返回的就是3.
2:
roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:
pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!
4:对于一般add、subtract、multiply方法的小数位格式化如下:
BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("mData=" + mData);
----结果:----- mData=9.66