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

1 public class Test_1 {
2 public static void main(String[] args) {
3 System.out.println(0.06+0.01);
4 System.out.println(1.0-0.42);
5 System.out.println(4.015*100);
6 System.out.println(303.1/1000);
7 }
8
9 }

运行结果如下。

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对象。

1 BigDecimal b1 = new BigDecimal(Double.toString(0.48));
2 BigDecimal b2 = BigDecimal.valueOf(0.48);

对于常用的加,减,乘,除,BigDecimal类提供了相应的成员方法。

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

进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。

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

 1 public class Arith {
2 /**
3 * 提供精确加法计算的add方法
4 * @param value1 被加数
5 * @param value2 加数
6 * @return 两个参数的和
7 */
8 public static double add(double value1,double value2){
9 BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
10 BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
11 return b1.add(b2).doubleValue();
12 }
13
14 /**
15 * 提供精确减法运算的sub方法
16 * @param value1 被减数
17 * @param value2 减数
18 * @return 两个参数的差
19 */
20 public static double sub(double value1,double value2){
21 BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
22 BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
23 return b1.subtract(b2).doubleValue();
24 }
25
26 /**
27 * 提供精确乘法运算的mul方法
28 * @param value1 被乘数
29 * @param value2 乘数
30 * @return 两个参数的积
31 */
32 public static double mul(double value1,double value2){
33 BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
34 BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
35 return b1.multiply(b2).doubleValue();
36 }
37
38 /**
39 * 提供精确的除法运算方法div
40 * @param value1 被除数
41 * @param value2 除数
42 * @param scale 精确范围
43 * @return 两个参数的商
44 * @throws IllegalAccessException
45 */
46 public static double div(double value1,double value2,int scale) throws IllegalAccessException{
47 //如果精确范围小于0,抛出异常信息
48 if(scale<0){
49 throw new IllegalAccessException("精确度不能小于0");
50 }
51 BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
52 BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
53 return b1.divide(b2, scale).doubleValue();
54 }
55 }

转:http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html

使用BigDecimal进行精确运算的更多相关文章

  1. BigDecimal - Java精确运算

    (1).浮点数精确计算 项目中一直存在一个问题,就是每次报表统计的物资金额和实际的金额要差那么几分钱,和实际金额不一致,让客户觉得总是不那么舒服,原因是因为我们使用java的浮点类型double来定义 ...

  2. 使用BigDecimal进行精确运算以及格式化输出数字

    一.引言    借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供 ...

  3. 使用Java BigDecimal进行精确运算

    首先我们先来看如下代码示例: public class Test_1 {     public static void main(String[] args) {         System.out ...

  4. (转)使用BigDecimal进行精确运算

    场景:在进行支付业务的金额计算时,通常采用BigDecimal类型的数据,并没有看到常见的int double类型,所以有必要好好学习下BigDecimal的常用用法. 1 误区 首先我们先来看如下代 ...

  5. 电商网站中价格的精确计算(使用BigDecimal进行精确运算(实现加减乘除运算))

    使用BigDecimal的String的构造器.商业计算中,使用bigdecimal的String构造器,一定要用. 重要的事情说三遍: 商业计算中,使用bigdecimal的String构造器! 商 ...

  6. BigDecimal进行精确运算demo工具类

    package com.js.ai.modules.pointwall.interfac; import java.math.BigDecimal; public class TestDigDecim ...

  7. BigDecimal进行精确运算

    public class Test_1 { public static void main(String[] args) { System.out.println(0.06+0.01); System ...

  8. java精确运算

    public class ArithUtil { /** * 加法 * @param * @return double * @throws Exception * @author zhangyn * ...

  9. Java工具类(util) 之01- 数学运算工具(精确运算)

    数学运算工具(精确运算) /** * * @author maple * */ public abstract class AmountUtil { private AmountUtil() { } ...

随机推荐

  1. Live2D WebGL实现

    demo预览:http://www.kakinuma.date/l2d.html 官方:http://www.live2d.com/en/ sdk下载:https://link.zhihu.com/? ...

  2. [课程设计]Scrum 1.6 多鱼点餐系统开发进度

    [课程设计]Scrum 1.6 多鱼点餐系统开发进度(点餐页面按钮添加&修复) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4. ...

  3. js 循环切换图片

    function changeLot(){ var minIndex = 1; var maxIndex = 100; var curIndex = 10; var src = $("ul ...

  4. Golang里面使用protobuf(proto3)

    参考文章:https://developers.google.com/protocol-buffers/docs/gotutorial 1.执行指令: go envgo get github.com/ ...

  5. Centos 6.5安装oracle 11g

    (添加host)一.Centos 6.5 安装图形界面 gnome # yum groupinstall "Desktop" # yum groupinstall "X ...

  6. 如何用ABBYY FineReader识别图片中的文本

    ABBYY FineReader 12是一款OCR光学字符识别软件,能够快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,让电脑处理更具效率,摆脱从前的烦恼,告别耗时费力 ...

  7. sokite

    <?php interface Proto { //连接 function conn($url); //发送get请求 function get(); //发送post请求 function p ...

  8. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

  9. h5的拖放(drag和drop)

    被拖曳元素发生的事件=== ondragstart:拖拽元素开始被拖拽的时候触发 ondragend:拖拽完成后触发 目标元素发生的事件=== ondragenter:拖曳元素进入目标元素的时候触发 ...

  10. C#:优惠券代码

    static Random random = new Random(); List<string> generatedVouchers = new List<string>() ...