因为计算机无法精确表示浮点数,所以在进行数字运算时,如果有 double 或 float 类型的浮点数参与计算,容易出现计算不准确的情况。在一些对精度要求很高的系统中,需要使用 BigDecimal 类来进行精确运行。
使用构造器方法创建对象,有多种不同的入参,常见的方法如下:
BigDecimal 有多种静态方法可以创建对象,常见的几种方法如下所示:
以上几种创建 BigDecimal 的 demo 如下所示。
public static void main(String[] args) {BigDecimal num1 = new BigDecimal("123.092");System.out.println(num1);// 123.092// 不推荐此种方法BigDecimal num2 = new BigDecimal(123.092);System.out.println(num2);// 123.0919999999999987494447850622236728668212890625BigDecimal num3 = BigDecimal.valueOf(1234.5678);System.out.println(num3);// 1234.5678long num4 = 1234;BigDecimal num5 = BigDecimal.valueOf(num4);System.out.println(num5);// 1234BigDecimal num6 = BigDecimal.valueOf(num4, 3);System.out.println(num6);// 1.234}
BigDecimal 几种常见计算方法如下所示。
操作方法 | 函数 |
---|---|
加法 | public BigDecimal add(BigDecimal augend) |
减法 | public BigDecimal subtract(BigDecimal subtrahend) |
乘法 | public BigDecimal multiply(BigDecimal multiplicand) |
除法(限定能除尽的情况,如果除不尽会抛出异常java.lang.ArithmeticException) | public BigDecimal divide(BigDecimal divisor) |
除法(可设置相除结果保留精度,无论是否可以除尽,都可以用该方法设置精度) | public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) |
求余 | public BigDecimal remainder(BigDecimal divisor) |
求相反数 | public BigDecimal negate() |
以上几种操作方法的 demo 如下所示。
public static void main(String[] args) {BigDecimal bignum1 = new BigDecimal("10");BigDecimal bignum2 = new BigDecimal("2");BigDecimal bignum3;// 加法bignum3 = bignum1.add(bignum2);System.out.println("和是:" + bignum3);// 和是:12// 减法bignum3 = bignum1.subtract(bignum2);System.out.println("差是:" + bignum3);// 差是:8// 乘法bignum3 = bignum1.multiply(bignum2);System.out.println("积是:" + bignum3);// 积是:20// 除法(可除尽时)bignum3 = bignum1.divide(bignum2);System.out.println("商是:" + bignum3);// 商是:5// 除法(设置精度及舍入模式)BigDecimal a = new BigDecimal("10");BigDecimal b = new BigDecimal("3");BigDecimal c = a.divide(b, 3, RoundingMode.HALF_UP);System.out.println("商是:" + c);// 商是:3.333// 求余数BigDecimal d = new BigDecimal("5");BigDecimal e = new BigDecimal("3");System.out.println(d.remainder(e));// 2// 求余数BigDecimal f = new BigDecimal("5.5");BigDecimal g = new BigDecimal("3.1");System.out.println(f.remainder(g));// 2.4// 求相反数BigDecimal h = new BigDecimal("-5.4");BigDecimal i = h.negate();System.out.println(i);// 5.4}
BigDecimal 有多种方法可以设置精度(即设置几位小数)。分述如下。
可以通过 DecimalFormat 设置保留的格式,demo 如下所示。如何编写 DecimalFormat,可以参考网上的介绍,此处不做介绍。
public static void main(String[] args) {// 格式化两位有效数字(四舍五入)DecimalFormat df = new DecimalFormat("0.00");double num1 = 0.145926;System.out.println(df.format(num1));// 0.15}
可以调用 BigDecimal 的 setScale(int newScale) 方法来设置精度,其中传入参数即保留的小数位数。该方法要求请求的操作具有精确的结果,否则会抛出 ArithmeticException。
public static void main(String[] args) {BigDecimal num1 = new BigDecimal("1234");BigDecimal num2 = num1.setScale(1);System.out.println(num2);// 1234.0BigDecimal num3 = new BigDecimal("1234.45");BigDecimal num4 = num3.setScale(1);System.out.println(num4);// 此处抛出异常:java.lang.ArithmeticException: Rounding necessary}
通过调用 BigDecimal 的 setScale(int newScale, int roundingMode) 方法,传入保留的小数位数 newScale 以及舍入模式 roundingMode(Java BigDecimal 的舍入模式(RoundingMode)详解),可以实现精度设置,demo 如下所示。
public static void main(String[] args) {BigDecimal num1 = new BigDecimal("1234.455");BigDecimal num2 = num1.setScale(2, BigDecimal.ROUND_HALF_UP);System.out.println(num2);// 1234.46System.out.println(num2.doubleValue());// 1234.46}
public static void main(String[] args) {BigDecimal num1 = new BigDecimal("1.45");BigDecimal num2 = new BigDecimal("2.625");BigDecimal ans = num1.multiply(num2).setScale(2, BigDecimal.ROUND_HALF_UP);System.out.println(ans);// 3.81System.out.println(ans.doubleValue());// 3.81System.out.println(ans.intValue());// 3}
public static void main(String[] args) {BigDecimal num1 = new BigDecimal("10.45");BigDecimal num2 = new BigDecimal("2.625");BigDecimal ans = num1.divide(num2, 2, BigDecimal.ROUND_HALF_UP);System.out.println(ans);// 3.98System.out.println(ans.doubleValue());// 3.98System.out.println(ans.intValue());// 3}