浅谈Java中BigDecimal类的使用

一、先观察一下这句代码的打印结果是多少?

System.out.println(0.06+0.01);

正确答案:0.06999999999999999,有人会问为什么不是0.07呢?

解析:因为计算机是二进制处理数据的。浮点数没有办法是用二进制进行精确表示,会失去一定的精确度,有些浮点数运算也会产生一定的误差。

针对这种情况Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

二、BigDecimal类的基本使用

1、使用步骤

     ①先用float或者double变量构建BigDecimal对象。

               通常可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。
                BigDecimal b1 = new BigDecimal(Double.toString(0.48));  //参数必须是是字符串类型
                BigDecimal b2 = BigDecimal.valueOf(0.48);

     ②在通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。

                public BigDecimal add(BigDecimal value);                        //加法
                public BigDecimal subtract(BigDecimal value);                 //减法 
                public BigDecimal multiply(BigDecimal value);                 //乘法
                public BigDecimal divide(BigDecimal value);                    //除法

     ③最后把BigDecimal对象转换成float,double,int等类型。

               可以使用floatValue(),doubleValue()等方法转换成基本类型

2、案例

                //损失精度
Double d1 = 0.06;
Double d2 = 0.01;
System.out.println(d1+d2);  // 0.06999999999999999
                //精确计算
BigDecimal b1 = BigDecimal.valueOf(d1);
BigDecimal b2 = new BigDecimal(d2);
BigDecimal sum = b1.add(b2);  // 加法
System.out.println(sum.doubleValue()); // 0.07

3、工具类

package Demo1;
import java.math.BigDecimal;
/**
 * 浮点型数据精确运算的工具类 提供加,减,乘,除运算的方法
 * */
public class ArithUtil {
/**
* 提供精确加法计算的add方法

* @param value1
*            被加数
* @param value2
*            加数
* @return 两个参数的和
*/
public static double add(double value1, double value2) {
BigDecimal b1 = new BigDecimal(Double.toString(value1));
BigDecimal b2 = new BigDecimal(Double.toString(value2));
return b1.add(b2).doubleValue();


/**
* 提供精确减法运算的sub方法

* @param value1
*            被减数
* @param value2
*            减数
* @return 两个参数的差
*/
public static double sub(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.subtract(b2).doubleValue();
}

/**
* 提供精确乘法运算的mul方法

* @param value1
*            被乘数
* @param value2
*            乘数
* @return 两个参数的积
*/
public static double mul(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.multiply(b2).doubleValue();
}

/**
* 提供精确的除法运算方法div

* @param value1
*            被除数
* @param value2
*            除数
* @param scale
*            精确范围
* @return 两个参数的商
* @throws IllegalAccessException
*/
public static double div(double value1, double value2, int scale)
throws IllegalAccessException {
// 如果精确范围小于0,抛出异常信息
if (scale < 0) {
throw new IllegalAccessException("精确度不能小于0");
}
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.divide(b2, scale).doubleValue();
}
}

ps:BigDecimal类里的api大家有兴趣可以自行研究一下......

scale 精确范围

negate 取反

b1.compareTo(b2)  比较大小(即左边比右边数大,返回1,相等返回0,比右边小返回-1。注意 不可用equals进行相等的判断,equals 比较是两个BigDecimal对象的地址。)

4、BigDecimal格式化

通常使用NumberFormat类的format()方法进行格式化,以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

public static void main(String[] args) {
   NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用 
   NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用 
   percent.setMaximumFractionDigits(3); //百分比小数点最多3位     
   BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额
   BigDecimal interestRate = new BigDecimal("0.008"); //利率   
   BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
   System.out.println("贷款金额:\t" + currency.format(loanAmount)); 
   System.out.println("利率:\t" + percent.format(interestRate)); 
   System.out.println("利息:\t" + currency.format(interest)); 
}

打印结果:贷款金额: ¥15,000.48
                利率: 0.8%
                利息: ¥120.00

猜你喜欢

转载自blog.csdn.net/qq_15901351/article/details/80556576