关闭

BigDecimal自学笔记

266人阅读 评论(0) 收藏 举报

先看看下面这个例子:

public class DoubleTest1 {
	public static void main(String[] args) {
		System.out.println("0.05+0.01="+(0.05+0.01));
		System.out.println("1.0-0.42="+(1.0-0.42));
		System.out.println("4.015*100="+(4.015*100));
		System.out.println("123.3/100="+(123.3/100));
	}
}
 运行结果:

0.05+0.01=0.060000000000000005

1.0-0.42=0.5800000000000001

4.015*100=401.49999999999994

123.3/100=1.2329999999999999

 

上面的例子表明,java的double类型会发生精度丢失,尤其在进行算术运算时更容易发生这种情况。(不仅java,很多语言都存在这样的问题)

当程序使用new BigDecimal(0.1)来创建一个BigDecimal对象时,它的值并不是0.1,实际上等于0.10000000000000055435324324233224.这是因为0.1无法准确地表示为double浮点数,所以传入BigDecimal构造器的值不会正好等于0.1(虽然表面上等于该值)

 

如果使用BigDecimal(String val)构造器的结果是可预知的——例如new BigDecimal("0.1")将创建一个BigDecimal,它正好等于预期的0.1,因此通常建议优先使用基于String的构造器。

 

如果必须使用double浮点数作为BigDecimal构造器的参数时,不要直接将double浮点数作为构造器参数创建BigDecimal对象,而是应该通过BigDecimal.valueOf(double value)静态方法来创建BigDecimal对象。

 

import java.math.BigDecimal;
public class BigDecimalTest {
	public static void main(String[] args) {
		BigDecimal f1 = new BigDecimal("0.05");
		BigDecimal f2 = BigDecimal.valueOf(0.01);
		BigDecimal f3 = new BigDecimal(0.05);
		 
		System.out.println("使用String作为BigDecimal构造器参数:");
		System.out.println("0.05 + 0.01 = " + f1.add(f2));
		System.out.println("0.05 - 0.01 = " + f1.subtract(f2));
		System.out.println("0.05 * 0.01 = " + f1.multiply(f2));
		System.out.println("0.05 / 0.01 = " + f1.divide(f2));
		 
		System.out.println("使用double作为BigDecimal构造器:");
		System.out.println("0.05 + 0.01 = " + f3.add(f2));
		System.out.println("0.05 - 0.01 = " + f3.subtract(f2));
		System.out.println("0.05 * 0.01 = " + f3.multiply(f2));
		System.out.println("0.05 / 0.01 = " + f3.divide(f2));
	}
}

 

运行结果:

使用String作为BigDecimal构造器参数:

0.05 + 0.01 = 0.06

0.05 - 0.01 = 0.04

0.05 * 0.01 = 0.0005

0.05 / 0.01 = 5

使用double作为BigDecimal构造器:

0.05 + 0.01 = 0.06000000000000000277555756156289135105907917022705078125

0.05 - 0.01 = 0.04000000000000000277555756156289135105907917022705078125

0.05 * 0.01 = 0.0005000000000000000277555756156289135105907917022705078125

0.05 / 0.01 = 5.000000000000000277555756156289135105907917022705078125

 

在金融项目中,需要对金额精确度高

 

package hb.bigdecimal;
import java.math.BigDecimal;

public class BigDecimalDemo {

	public static void main(String[]args){
		double v1 = 3.5;
		double v2 = 0.7;
//		BigDecimal result = add(v1, v2);
//		BigDecimal result = sub(v1, v2);
//		BigDecimal result = mul(v1, v2);
		BigDecimal result = div(v1, v2);
		System.out.println(result);
		
		BigDecimal a = new BigDecimal(998.01);  
		BigDecimal a1 = BigDecimal.valueOf(998.01);  
		BigDecimal b=new BigDecimal("100");  
		System.out.println(a.multiply(b));  
		System.out.println(a1.multiply(b));  //期望值一样
		  
		BigDecimal aa = new BigDecimal(135.95);  
		BigDecimal aa1 = new BigDecimal("135.95");  
		BigDecimal bb=new BigDecimal("100");  
		System.out.println(aa.multiply(bb));  
		System.out.println(aa1.multiply(bb));   //期望值一样
		  
		  
		BigDecimal test = new BigDecimal(4.015);  
		BigDecimal test2 = BigDecimal.valueOf(4.015);  
		BigDecimal test1 = new BigDecimal(100);  
		System.out.println(test.multiply(test1));
		System.out.println(test2.multiply(test1)); //期望值一样
		
		BigDecimal aa11 = new BigDecimal(135.95);  
		BigDecimal aa12 = new BigDecimal("135.95");  
		BigDecimal bb1=new BigDecimal("100");  
		BigDecimal result1=aa11.multiply(bb1); 
		BigDecimal result2=aa12.multiply(bb1);  //期望值一样
		//将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入
		System.out.println(result1.setScale(2,BigDecimal.ROUND_HALF_EVEN));
		System.out.println(result2.setScale(2,BigDecimal.ROUND_HALF_EVEN));
		
		
	}
	
	/**
	 * 用第一个数除以第二个数
	 * 提供精确的除法运算 当除不尽时,精确到小数点后10位,以后的数字四舍五入 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal div(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		//13表示小数点后面精确到多少位
		return b1.divide(b2, 13, BigDecimal.ROUND_HALF_UP);
	}
	
	/**
	 * 连个数相乘
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal mul(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2);
	}
	
	/**
	 * 计算第一个数减去第二个数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal sub(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2);
	}
	
	/**
	 * 计算两个数相加
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal add(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2);
	}
}

 运行结果:

5.0000000000000

99800.999999999999090505298227071762084960937500

99801.00

13594.99999999999886313162278383970260620117187500

13595.00

401.49999999999996802557689079549163579940795898437500

401.500

13595.00

13595.00

 

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:309844次
    • 积分:8710
    • 等级:
    • 排名:第2262名
    • 原创:1096篇
    • 转载:14篇
    • 译文:0篇
    • 评论:5条
    最新评论