使用BigDecimal进行精确运算

标签: bigdecimal 精确 运算 | 发表时间:2012-09-09 10:15 | 作者:chenssy
出处:http://blog.csdn.net

          首先我们先来看如下代码示例:

public class Test_1 {
	public static void main(String[] args) {
		System.out.println(0.06+0.01);
		System.out.println(1.0-0.42);
		System.out.println(4.015*100);
		System.out.println(303.1/1000);
	}
	
}


          运行结果如下。

         0.06999999999999999

         0.5800000000000001

         401.49999999999994

         0.30310000000000004

         你认为你看错了,但结果却是是这样的。问题在哪里呢?原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。

          其实java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

          在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

              1、用float或者double变量构建BigDecimal对象。

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

              3、把BigDecimal对象转换成float,double,int等类型。

          一般来说,可以使用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对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。

          下面是一个工具类,该工具类提供加,减,乘,除运算。

public class Arith {
	/**
	 * 提供精确加法计算的add方法
	 * @param value1 被加数
	 * @param value2 加数
	 * @return 两个参数的和
	 */
	public static double add(double value1,double value2){
		BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
		BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
		return b1.add(b2).doubleValue();
	}
	
	/**
	 * 提供精确减法运算的sub方法
	 * @param value1 被减数
	 * @param value2 减数
	 * @return 两个参数的差
	 */
	public static double sub(double value1,double value2){
		BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
		BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
		return b1.subtract(b2).doubleValue();
	}
	
	/**
	 * 提供精确乘法运算的mul方法
	 * @param value1 被乘数
	 * @param value2 乘数
	 * @return 两个参数的积
	 */
	public static double mul(double value1,double value2){
		BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
		BigDecimal b2 = new BigDecimal(Double.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 = new BigDecimal(Double.valueOf(value1));
		BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
		return b1.divide(b2, scale).doubleValue();	
	}
}


 

作者:chenssy 发表于2012-9-9 10:15:54 原文链接
阅读:17 评论:0 查看评论

相关 [bigdecimal 精确 运算] 推荐:

使用BigDecimal进行精确运算

- - CSDN博客推荐文章
          首先我们先来看如下代码示例:.           运行结果如下.          你认为你看错了,但结果却是是这样的. 原因在于我们的计算机是二进制的. 浮点数没有办法是用二进制进行精确表示. 我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差.

为什么阿里巴巴禁止使用BigDecimal的equals方法做等值比较?

- - 掘金后端本月最热
BigDecimal,相信对于很多人来说都不陌生,很多人都知道他的用法,这是一种java.math包中提供的一种可以用来进行精确运算的类型. 很多人都知道,在进行金额表示、金额计算等场景,不能使用double、float等类型,而是要使用对精度支持的更好的BigDecimal. 所以,很多支付、电商、金融等业务中,BigDecimal的使用非常频繁.

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较

- - 掘金后端本月最热
BigDecimal 是 java.math 包中提供的一种可以用来进行精确运算的类型. 所以,在支付、电商等业务中,BigDecimal 的使用非常频繁. 而且其内部自带了很多方法,如加,减,乘,除等运算方法都是可以直接调用的. 除了需要用 BigDecimal 表示数字和进行数字运算以外,代码中还经常需要对于数字进行相等判断.

Web设计精确点滴

- 安淡名 - 所有文章 - UCD大社区
这篇文章说实际问题的,所以不多强调,下面是我总结的一些比较突出的细节问题,而且我一直认为这些问题比较严重,正因为这些都是基本问题,很容易解决的,但把这种忽略养成一种习惯性的“经验”那就“杯具”了,然而这些细节问题也不同程度的代表了你的工作态度. 当对一个位图的大小进行调整后,正常情况下会留下1px的毛边(如果你注意的话),边界会变得模糊,如果继续调整模糊度会加大,这个问题太不起眼了,以至于你无法用肉眼来理绘,我们先用商品图片举例子:.

骑车杀精,确有其事

- leafduo - 果壳网 guokr.com - 果壳网
一年一度的环法大赛总能吸引很多人的关注,一辆高科技碳架公路赛,一身帅气的骑行服锁鞋加上锃亮的头盔墨镜,还有闪耀的黄色领骑衫,那风一般的骑行速度以及冲线之后的美女和香槟成为众多人欣羡的对象. 而今年澳大利亚选手埃文斯(Cadel Evans)在环法夺冠,也大大刺激了澳大利亚的自行车销售业,看来又有不少澳大利亚人加入了自行车运动.

校正物理常量,让科学更精确

- Demojiang - 果壳网 guokr.com - 果壳网
你是否感觉到地球引力有所削弱. 近日,美国国家标准技术研究所(NIST)发布了自然界基本常数的国际推荐数值. 结果则是:万有引力略微有所“减弱”,电磁力有少量的“提升”,这使得整个物理学也少了一丝不确定性. 为了顾及不断进步的科学技术,每隔四年国家标准技术研究所和它的国际合作伙伴都将对物理基本常数进行校正,以保证像光速、万有引力常量(G)、普朗克常数这样的著名常量更加精确.

量子计算使未来原子钟更加精确

- Ra白菜 - 科学松鼠会
新一代原子钟的误差约为每370亿年1秒. 也就是说,经过从宇宙诞生到现在的时间,这个原子钟才会产生0.5秒的误差. 目前,最精确的时钟是科罗拉多州博尔德国家标准与技术研究所去年制造的量子逻辑钟,它的误差约为每37亿年1秒. 而未来采用新的改进方式的原子钟又可能将发生1秒误差的时间延长到370亿年,这比宇宙年龄的两倍还要大.

毛泽东对邓、华、江、叶等人的精确预测

- 小小草beta - 废话一筐
    毛对邓、华、江、叶等人的精确预测.     毛说:“小平看不起那些人,我在还可以,我死了,谁也压不住他. 他这个人对三自一包那些东西还是有感情的,对走资派恨不起来.     当问起毛泽东同越共中央第一书记黎笋说邓小平是少壮派是否有意传位给邓时,毛泽东说:“他只要表态对文革有个基本认识,就不能动.

精确测量古代丝织品日期

- han - Solidot
博物馆中收藏的丝绸衣服和丝织品因为脆弱和珍贵而难以确定日期. 因为传统的碳测年法需要较大的样本而会损坏丝织品,历史学家只能靠间接证据和猜测去估计古代丝绸的制造日期. 一种新的超灵敏化学技术可以解决这一难题. 化学家Mehdi Moini的技术是基于蛋白质左旋氨基酸变成右旋氨基酸的趋势,碳基分子方向从左旋变成右旋虽然罕见,但一直以稳定速率发生着,时间越长越显著.

日本利用大数据预测流感 结果精确

- - TECH2IPO创见
日本 NHK 网站报道,日本国内有一个网站,你只要打开这个网站用自己的 Twitter 账号登录,就可以在短时间内通过数万条 Twitter 找出可能感冒的人,并通过过去的感冒情况和今日的感冒情况进行分析(以及统计目前发烧以及嗓子痛的患者数量),另外该程序还会结合气温和湿度的变化来预测将来感冒的流行情况,并制作一个“易感冒日历”.