前提
对于需要精确计算得场景和一些需要精确保留小数位的场景,可以使用BigDeciaml来做操作
举个例子,两数相乘或者相除:
java"> double a = 1.235;double b = 100.00;System.out.println(a * b); // 期望结果:123.4double c = 123.30;double d = 100.00;System.out.println(c / d); //期望结果:1.233
实际结果:
123.50000000000001
1.2329999999999999
使用BigDeciaml
java"> BigDecimal a = new BigDecimal("1.235");BigDecimal b = new BigDecimal("100.00");BigDecimal c = new BigDecimal("123.30");BigDecimal d = new BigDecimal("100.00");System.out.println(a.multiply(b));System.out.println(c.divide(d));
实际结果:
123.50000
1.233
构建
使用字符串来构造BigDecimal对象,如下
java">BigDecimal bd = new BigDecimal("0.1");
错误做法:
下面这种,使用double类型的参数构造BigDecimal,会有精度问题,不要使用
java">BigDecimal bd = new BigDecimal(0.1);
结果:
0.1000000000000000055511151231257827021181583404541015625
常用方法
- 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对象中的值转换成整数
- compareTo(BigDecimal val);
比较大小:-1小于;0相等;1大于
java"> System.out.println(new BigDecimal("0.1").compareTo(new BigDecimal("0.2")));System.out.println(new BigDecimal("0.2").compareTo(new BigDecimal("0.1")));System.out.println(new BigDecimal("0.123").compareTo(new BigDecimal("0.123000000")));
结果:
-1
1
0
- BigDecimal setScale(int newScale, int roundingMode)
roundingMode:
public static final int ROUND_HALF_UP = 4; //向上取
public static final int ROUND_HALF_DOWN = 5; //向下取
.......
java">BigDecimal bigDecimal = new BigDecimal("0.12345678").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(bigDecimal);
结果:
0.12
工具类
java">
public class BigDecimalUtils {/*** 除法默认保留精度*/private static final int DEF_DIV_SCALE = 10;/*** 默认舍入模式(ROUND_HALF_UP:四舍五入)*/private static final int DEF_ROUNDING_MODE = BigDecimal.ROUND_HALF_UP;private static final String FORMAT_1 = "#.##";/*** 将字符串转换为 BigDecimal** @param value* @return*/public static BigDecimal of(String value) {return value == null ? null : new BigDecimal(value);}/*** v1 + v2** @param v1 被加数* @param v2 加数* @return 两个参数的和*/public static BigDecimal add(BigDecimal v1, BigDecimal v2) {return v1.add(v2);}/*** args[0] + args[1] + ... + args[n]** @param args* @return*/public static BigDecimal add(BigDecimal... args) {if (args == null || args.length <= 1) {throw new IllegalArgumentException("args Contains at least two parameters");}BigDecimal result = args[0];for (int i = 1; i < args.length; i++) {result = add(result, args[i]);}return result;}/*** v1 - v2** @param v1 被加数* @param v2 加数* @return 两个参数的和*/public static BigDecimal subtract(BigDecimal v1, BigDecimal v2) {return v1.subtract(v2);}/*** args[0] - args[1] - ... - args[n]** @param args* @return*/public static BigDecimal subtract(BigDecimal... args) {if (args == null || args.length <= 1) {throw new IllegalArgumentException("args Contains at least two parameters");}BigDecimal result = args[0];for (int i = 1; i < args.length; i++) {result = subtract(result, args[i]);}return result;}/*** v1 * v2** @param v1 被乘数* @param v2 乘数* @return 两个参数的积*/public static BigDecimal multiply(BigDecimal v1, BigDecimal v2) {return v1.multiply(v2);}/*** args[0] * args[1] * ... * args[n]** @return 两个参数的积*/public static BigDecimal multiply(BigDecimal... args) {if (args == null || args.length <= 1) {throw new IllegalArgumentException("args Contains at least two parameters");}BigDecimal result = args[0];for (int i = 1; i < args.length; i++) {result = multiply(result, args[i]);}return result;}/*** v1 / v2** @param v1 被乘数* @param v2 乘数* @return 两个参数的积*/public static BigDecimal divide(BigDecimal v1, BigDecimal v2) {return v1.divide(v2, DEF_DIV_SCALE, DEF_ROUNDING_MODE);}/*** args[0] / args[1] / ... / args[n]** @return 两个参数的积*/public static BigDecimal divide(BigDecimal... args) {if (args == null || args.length <= 1) {throw new IllegalArgumentException("args Contains at least two parameters");}BigDecimal result = args[0];for (int i = 1; i < args.length; i++) {result = divide(result, args[i]);}return result;}/*** 四舍五入,保留两位小数** @param d* @return*/public static BigDecimal round(BigDecimal d) {if (d == null) {return null;}return d.setScale(2, BigDecimal.ROUND_HALF_UP);}/*** v1>v2?** @param v1* @param v2* @return*/public static boolean gt(BigDecimal v1, BigDecimal v2) {return v1.compareTo(v2) > 0;}/*** v1 == v2** @param v1* @param v2* @return*/public static boolean eq(BigDecimal v1, BigDecimal v2) {return v1.compareTo(v2) == 0;}/*** 判断 values 是否等于 0?** @param value* @return*/public static boolean eq0(BigDecimal value) {return BigDecimal.ZERO.compareTo(value) == 0;}/*** v1>=v2?** @param v1* @param v2* @return*/public static boolean ge(BigDecimal v1, BigDecimal v2) {return v1.compareTo(v2) >= 0;}/*** v1<v2?** @param v1* @param v2* @return*/public static boolean lt(BigDecimal v1, BigDecimal v2) {return v1.compareTo(v2) < 0;}/*** 格式化,保留2为小数** @param value* @return*/public static String format(BigDecimal value) {if (value == null) {return null;}DecimalFormat df = new DecimalFormat(FORMAT_1);return df.format(value);}/*** 格式化** @param value* @param pattern 模式字符串,如:#.##* @return*/public static String format(BigDecimal value, String pattern) {if (value == null) {return null;}DecimalFormat df = new DecimalFormat(pattern);return df.format(value);}}