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测试
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就是解决这个问题的。
直接在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 的加减乘除和“+”“-”“*”“/”有啥区别的主要内容,如果未能解决你的问题,请参考以下文章