Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作啦!
(一)BigDecimal类的常用的几个构造方法
- BigDecimal(int):将int表示形式转换为BigDecimal对象
- BigDecimal(String) :将字符串表示形式转换为BigDecimal对象
- BigDecimal(double):将double表示形式转换为BigDecimal对象
(二)BigDecimal类的常用方法
- add(BigDecimal):BigDecimal对象中的值相加,返回BigDecimal对象
- subtract(BigDecimal):BigDecimal对象中的值相减,返回BigDecimal对象
- multiply(BigDecimal):BigDecimal对象中的值相乘,返回BigDecimal对象
- divide(BigDecimal):BigDecimal对象中的值相除,返回BigDecimal对象
- toString():将BigDecimal对象中的值转换成字符串
- doubleValue():将BigDecimal对象中的值转换成双精度数
- floatValue():将BigDecimal对象中的值转换成单精度数
- longValue():将BigDecimal对象中的值转换成长整数
- intValue():将BigDecimal对象中的值转换成整数
下面分享一个用于高精确处理常用的数学运算类
1 package com.per.test; 2 3 import java.math.BigDecimal; 4 5 /** 6 * 用于高精确处理常用的数学运算 7 * Created by lijuan on 2016/8/27. 8 */ 9 public class ArithmeticUtils { 10 //默认除法运算精度 11 private static final int DEF_DIV_SCALE = 10; 12 13 /** 14 * 提供精确的加法运算 15 * 16 * @param v1 被加数 17 * @param v2 加数 18 * @return 两个参数的和 19 */ 20 21 public static double add(double v1, double v2) { 22 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 23 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 24 return b1.add(b2).doubleValue(); 25 } 26 27 /** 28 * 提供精确的加法运算 29 * 30 * @param v1 被加数 31 * @param v2 加数 32 * @return 两个参数的和 33 */ 34 public static BigDecimal add(String v1, String v2) { 35 BigDecimal b1 = new BigDecimal(v1); 36 BigDecimal b2 = new BigDecimal(v2); 37 return b1.add(b2); 38 } 39 40 /** 41 * 提供精确的加法运算 42 * 43 * @param v1 被加数 44 * @param v2 加数 45 * @param scale 保留scale 位小数 46 * @return 两个参数的和 47 */ 48 public static String add(String v1, String v2, int scale) { 49 if (scale < 0) { 50 throw new IllegalArgumentException( 51 "The scale must be a positive integer or zero"); 52 } 53 BigDecimal b1 = new BigDecimal(v1); 54 BigDecimal b2 = new BigDecimal(v2); 55 return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 56 } 57 58 /** 59 * 提供精确的减法运算 60 * 61 * @param v1 被减数 62 * @param v2 减数 63 * @return 两个参数的差 64 */ 65 public static double sub(double v1, double v2) { 66 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 67 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 68 return b1.subtract(b2).doubleValue(); 69 } 70 71 /** 72 * 提供精确的减法运算。 73 * 74 * @param v1 被减数 75 * @param v2 减数 76 * @return 两个参数的差 77 */ 78 public static BigDecimal sub(String v1, String v2) { 79 BigDecimal b1 = new BigDecimal(v1); 80 BigDecimal b2 = new BigDecimal(v2); 81 return b1.subtract(b2); 82 } 83 84 /** 85 * 提供精确的减法运算 86 * 87 * @param v1 被减数 88 * @param v2 减数 89 * @param scale 保留scale 位小数 90 * @return 两个参数的差 91 */ 92 public static String sub(String v1, String v2, int scale) { 93 if (scale < 0) { 94 throw new IllegalArgumentException( 95 "The scale must be a positive integer or zero"); 96 } 97 BigDecimal b1 = new BigDecimal(v1); 98 BigDecimal b2 = new BigDecimal(v2); 99 return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 100 } 101 102 /** 103 * 提供精确的乘法运算 104 * 105 * @param v1 被乘数 106 * @param v2 乘数 107 * @return 两个参数的积 108 */ 109 public static double mul(double v1, double v2) { 110 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 111 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 112 return b1.multiply(b2).doubleValue(); 113 } 114 115 /** 116 * 提供精确的乘法运算 117 * 118 * @param v1 被乘数 119 * @param v2 乘数 120 * @return 两个参数的积 121 */ 122 public static BigDecimal mul(String v1, String v2) { 123 BigDecimal b1 = new BigDecimal(v1); 124 BigDecimal b2 = new BigDecimal(v2); 125 return b1.multiply(b2); 126 } 127 128 129 /** 130 * 提供精确的乘法运算 131 * 132 * @param v1 被乘数 133 * @param v2 乘数 134 * @param scale 保留scale 位小数 135 * @return 两个参数的积 136 */ 137 public static double mul(double v1, double v2, int scale) { 138 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 139 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 140 return round(b1.multiply(b2).doubleValue(), scale); 141 } 142 143 /** 144 * 提供精确的乘法运算 145 * 146 * @param v1 被乘数 147 * @param v2 乘数 148 * @param scale 保留scale 位小数 149 * @return 两个参数的积 150 */ 151 public static String mul(String v1, String v2, int scale) { 152 if (scale < 0) { 153 throw new IllegalArgumentException( 154 "The scale must be a positive integer or zero"); 155 } 156 BigDecimal b1 = new BigDecimal(v1); 157 BigDecimal b2 = new BigDecimal(v2); 158 return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 159 } 160 161 /** 162 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 163 * 小数点以后10位,以后的数字四舍五入 164 * 165 * @param v1 被除数 166 * @param v2 除数 167 * @return 两个参数的商 168 */ 169 170 public static double div(double v1, double v2) { 171 return div(v1, v2, DEF_DIV_SCALE); 172 } 173 174 /** 175 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 176 * 定精度,以后的数字四舍五入 177 * 178 * @param v1 被除数 179 * @param v2 除数 180 * @param scale 表示表示需要精确到小数点以后几位。 181 * @return 两个参数的商 182 */ 183 public static double div(double v1, double v2, int scale) { 184 if (scale < 0) { 185 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 186 } 187 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 188 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 189 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 190 } 191 192 /** 193 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 194 * 定精度,以后的数字四舍五入 195 * 196 * @param v1 被除数 197 * @param v2 除数 198 * @param scale 表示需要精确到小数点以后几位 199 * @return 两个参数的商 200 */ 201 public static String div(String v1, String v2, int scale) { 202 if (scale < 0) { 203 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 204 } 205 BigDecimal b1 = new BigDecimal(v1); 206 BigDecimal b2 = new BigDecimal(v1); 207 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString(); 208 } 209 210 /** 211 * 提供精确的小数位四舍五入处理 212 * 213 * @param v 需要四舍五入的数字 214 * @param scale 小数点后保留几位 215 * @return 四舍五入后的结果 216 */ 217 public static double round(double v, int scale) { 218 if (scale < 0) { 219 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 220 } 221 BigDecimal b = new BigDecimal(Double.toString(v)); 222 return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 223 } 224 225 /** 226 * 提供精确的小数位四舍五入处理 227 * 228 * @param v 需要四舍五入的数字 229 * @param scale 小数点后保留几位 230 * @return 四舍五入后的结果 231 */ 232 public static String round(String v, int scale) { 233 if (scale < 0) { 234 throw new IllegalArgumentException( 235 "The scale must be a positive integer or zero"); 236 } 237 BigDecimal b = new BigDecimal(v); 238 return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 239 } 240 241 242 /** 243 * 取余数 244 * 245 * @param v1 被除数 246 * @param v2 除数 247 * @param scale 小数点后保留几位 248 * @return 余数 249 */ 250 public static String remainder(String v1, String v2, int scale) { 251 if (scale < 0) { 252 throw new IllegalArgumentException( 253 "The scale must be a positive integer or zero"); 254 } 255 BigDecimal b1 = new BigDecimal(v1); 256 BigDecimal b2 = new BigDecimal(v2); 257 return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 258 } 259 260 /** 261 * 取余数 BigDecimal 262 * 263 * @param v1 被除数 264 * @param v2 除数 265 * @param scale 小数点后保留几位 266 * @return 余数 267 */ 268 public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) { 269 if (scale < 0) { 270 throw new IllegalArgumentException( 271 "The scale must be a positive integer or zero"); 272 } 273 return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); 274 } 275 276 /** 277 * 比较大小 278 * 279 * @param v1 被比较数 280 * @param v2 比较数 281 * @return 如果v1 大于v2 则 返回true 否则false 282 */ 283 public static boolean compare(String v1, String v2) { 284 BigDecimal b1 = new BigDecimal(v1); 285 BigDecimal b2 = new BigDecimal(v2); 286 int bj = b1.compareTo(b2); 287 boolean res; 288 if (bj > 0) 289 res = true; 290 else 291 res = false; 292 return res; 293 } 294 }