java中BigDecimal 的加减乘除和“+”“-”“*”“/”有啥区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中BigDecimal 的加减乘除和“+”“-”“*”“/”有啥区别相关的知识,希望对你有一定的参考价值。

看了下add的源码,有位运算等

BigDecimal用作商业计算的。

BigDecimal aDouble =new BigDecimal(1.22);     输出:1.2199999999999999733546474089962430298328399658203125

BigDecimal aString = new BigDecimal("1.22");   输出:1.22

以上两者输出结果是不一样的。

原因:

double的构造方法有不可预知性。

String的构造方法是固定的值。

所以如果类型是Double的话,而且需要精确计算,就用下面方法:

Double.toString(double)方法,可以先转为String,然后再用new BigDecimal("")构造方法。

注意:BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值

Demo测试

    public static final void main(String[] args) 
        BigDecimal aBigDecimal = new BigDecimal("1.1");
        BigDecimal bBigDecimal = new BigDecimal("2.0");
        
        BigDecimal subtract = bBigDecimal.subtract(aBigDecimal);
        System.out.println("使用BigDecimal进行相减计算:" + subtract.doubleValue());

        System.out.println("直接相减: " + (2.0 - 1.1));

结果:

使用BigDecimal进行相减计算:0.9
直接相减: 0.8999999999999999

参考技术A

    你首先要理解java中有数据运算时候有精度丢失问题。

    比如 1 - 0.9这个计算的结果不是你想的0.1,而是0.09999999999999998。

    BigDecimal就是解决这个问题的。

参考技术B

直接在java类中进行运算,可以明显看出,直接运算会产生精度丢失!!!

java工具类-BigDecimal

  1 package hello;
  2 
  3 import java.math.BigDecimal;
  4 
  5 /**
  6  * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
  7  */
  8 public class BigDecimalUtil {
  9 
 10     // 默认除法运算精度
 11     private static final int DEF_DIV_SCALE = 10;
 12 
 13     // 这个类不能实例化
 14     private BigDecimalUtil() {
 15     }
 16 
 17     /**
 18      * 提供精确的加法运算。
 19      * 
 20      * @param v1
 21      *            被加数
 22      * @param v2
 23      *            加数
 24      * @return 两个参数的和
 25      */
 26     public static double add(double v1, double v2) {
 27         BigDecimal b1 = new BigDecimal(Double.toString(v1));
 28         BigDecimal b2 = new BigDecimal(Double.toString(v2));
 29         return b1.add(b2).doubleValue();
 30     }
 31 
 32     /**
 33      * 提供精确的减法运算。
 34      * 
 35      * @param v1
 36      *            被减数
 37      * @param v2
 38      *            减数
 39      * @return 两个参数的差
 40      */
 41     public static double sub(double v1, double v2) {
 42         BigDecimal b1 = new BigDecimal(Double.toString(v1));
 43         BigDecimal b2 = new BigDecimal(Double.toString(v2));
 44         return b1.subtract(b2).doubleValue();
 45     }
 46 
 47     /**
 48      * 提供精确的乘法运算。
 49      * 
 50      * @param v1
 51      *            被乘数
 52      * @param v2
 53      *            乘数
 54      * @return 两个参数的积
 55      */
 56     public static double mul(double v1, double v2) {
 57         BigDecimal b1 = new BigDecimal(Double.toString(v1));
 58         BigDecimal b2 = new BigDecimal(Double.toString(v2));
 59         return b1.multiply(b2).doubleValue();
 60     }
 61 
 62     /**
 63      * 提供精确的乘法运算。
 64      * 
 65      * @param v1
 66      *            被乘数
 67      * @param v2
 68      *            乘数
 69      * @param scale
 70      *            乘数
 71      * @return 两个参数的积
 72      */
 73     public static double mul(double v1, double v2, int scale) {
 74         BigDecimal b1 = new BigDecimal(Double.toString(v1));
 75         BigDecimal b2 = new BigDecimal(Double.toString(v2));
 76         BigDecimal r = b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);
 77         return r.doubleValue();
 78     }
 79 
 80     /**
 81      * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
 82      * 
 83      * @param v1
 84      *            被除数
 85      * @param v2
 86      *            除数
 87      * @return 两个参数的商
 88      */
 89     public static double div(double v1, double v2) {
 90         return div(v1, v2, DEF_DIV_SCALE);
 91     }
 92 
 93     /**
 94      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
 95      * 
 96      * @param v1
 97      *            被除数
 98      * @param v2
 99      *            除数
100      * @param scale
101      *            表示表示需要精确到小数点以后几位。
102      * @return 两个参数的商
103      */
104     public static double div(double v1, double v2, int scale) {
105         if (scale < 0) {
106             throw new IllegalArgumentException("The scale must be a positive integer or zero");
107         }
108         BigDecimal b1 = new BigDecimal(Double.toString(v1));
109         BigDecimal b2 = new BigDecimal(Double.toString(v2));
110         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
111     }
112 
113     /**
114      * 提供精确的小数位四舍五入处理。
115      * 
116      * @param v
117      *            需要四舍五入的数字
118      * @param scale
119      *            小数点后保留几位
120      * @return 四舍五入后的结果
121      */
122     public static double round(double v, int scale) {
123         if (scale < 0) {
124             throw new IllegalArgumentException("The scale must be a positive integer or zero");
125         }
126         BigDecimal b = new BigDecimal(Double.toString(v));
127         BigDecimal one = new BigDecimal("1");
128         return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
129     }
130 };

 

以上是关于java中BigDecimal 的加减乘除和“+”“-”“*”“/”有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

java中bigdecimal 类型的变量怎么相互加减乘除

java中BigDecimal 的加减乘除和“+”“-”“*”“/”有啥区别

java加减乘除是啥类

java BigDecimal实现精确加减乘除运算

Java进行数字计算 BigDecimal计算(加减乘除)

BigDecimal类型数据的加减乘除运算