Java之BigDecimal的学习
因为项目中需要精确计算,因此学习了以下bigdecimal这个类,以前感觉很难用,其实习惯了就行,他就是一个工具类。
以下摘自百度百科,仅仅是有用的。
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
BigDecimal一共有4个构造方法:
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。(不建议采用)
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
为什么不建议采用第二种构造方法?如下代码:
public static void main(String[] args) {
BigDecimal d1 = new BigDecimal(2);
BigDecimal d2 = new BigDecimal(2.3);
BigDecimal d3 = new BigDecimal("2.3");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
}
2
2.29999999999999982236431605997495353221893310546875
2.3
原因:JDK的描述:1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法
当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下:
public static void main(String[] args) {
BigDecimal d4 = BigDecimal.valueOf(2.3);
BigDecimal d5 = new BigDecimal(Double.toString(2.3));
System.out.println(d4);
System.out.println(d5);
}
2.3
2.3
public BigDecimal add(BigDecimal value); //加法
public BigDecimal subtract(BigDecimal value); //减法
public BigDecimal multiply(BigDecimal value); //乘法
public BigDecimal divide(BigDecimal value); //除法
工具类
import java.math.BigDecimal;
/**
* [说明/描述] BigDecimal工具类,解决String 转Double 损失精度的问题
*/
public class Arith {
//默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
//这个类不能实例化
private Arith(){
}
//加
public static double add(String v1,double v2){
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
//加
public static BigDecimal add(String v1,String v2){
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.add(b2);
}
/**
* //减
* [描述信息] <br>
* @author <br>
* @date 2018-11-19 下午4:10:04 <br>
* @param v1
* @param v2
* @return <br>
*/
public static BigDecimal sub(String v1,String v2){
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.subtract(b2);
}
/**
*
* [描述信息] //乘<br>
* @author <br>
* @date 2018-11-19 下午4:09:50 <br>
* @param v1
* @param v2
* @return <br>
*/
public static double mul(double v1,double v2){
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 除法运算
* [描述信息] <br>
* @author <br>
* @date 2018-11-19 下午4:09:33 <br>
* @param v1
* @param v2
* @param scale
* @return <br>
*/
public static double div(String v1,double v2,int scale){
if(scale<0){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static BigDecimal div(String v1,String v2,int scale){
if(scale<0){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP);
}
public static double round(double v,int scale){
if(scale<0){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static double StringToDouble(String v){
BigDecimal maxlng1 = new BigDecimal(v);
return maxlng1.doubleValue();
}
public static void main(String[] args) {
System.out.println(sub("0.10", "0.000"));
}
}