Appearance
BigDecimal
Similar to BigInteger
, BigDecimal
can represent a floating-point number of any size with completely accurate precision.
java
BigDecimal bd = new BigDecimal("123.4567");
System.out.println(bd.multiply(bd)); // 15241.55677489
BigDecimal
uses scale()
to represent the number of decimal places, for example:
java
BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,two decimal places
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0
Through BigDecimal
's stripTrailingZeros()
method, a BigDecimal
can be formatted into an equal BigDecimal but with BigDecimal
trailing 0 removed:
java
BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2 = d1.stripTrailingZeros();
System.out.println(d1.scale()); // 4
System.out.println(d2.scale()); // 2,Because 00 was removed
BigDecimal d3 = new BigDecimal("1234500");
BigDecimal d4 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d4.scale()); // -2
If a BigDecimal
's scale()
returns a negative number, for example, -2
, it means that the number is an integer and has two zeros at the end.
You can set scale
of a BigDecimal
. If the precision is lower than the original value, it will be rounded or truncated directly according to the specified method:
java
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal d1 = new BigDecimal("123.456789");
BigDecimal d2 = d1.setScale(4, RoundingMode.HALF_UP); // to the nearest whole number,123.4568
BigDecimal d3 = d1.setScale(4, RoundingMode.DOWN); // truncate directly,123.4567
System.out.println(d2);
System.out.println(d3);
}
}
When adding, subtracting, or multiplying BigDecimal
, the precision will not be lost. However, when performing division, there may be cases where the division cannot be completed. In this case, the precision and how to truncate must be specified:
java
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // Round to 10 decimal places
BigDecimal d4 = d1.divide(d2); // Error:ArithmeticException,Because it can’t be eliminated
You can also divide BigDecimal
and find the remainder at the same time:
java
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); // 102
System.out.println(dr[1]); // 0.105
}
}
When divideAndRemainder()
method is called, the returned array contains two BigDecimal
, which are the quotient and the remainder. The quotient is always an integer, and the remainder will not be greater than the divisor. We can use this method to determine whether two BigDecimal
are multiples of integers:
java
BigDecimal n = new BigDecimal("12.75");
BigDecimal m = new BigDecimal("0.15");
BigDecimal[] dr = n.divideAndRemainder(m);
if (dr[1].signum() == 0) {
// n is an integer multiple of m
}
Compare BigDecimal
When comparing whether the values of two BigDecimal
are equal, special attention should be paid to the fact that using equals()
method not only requires the values of the two BigDecimal
to be equal, but also requires their scale()
to be equal:
java
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("123.45600");
System.out.println(d1.equals(d2)); // false,Because the scale is different
System.out.println(d1.equals(d2.stripTrailingZeros())); // true,Because after d2 removes the tail 0, the scale becomes 3
System.out.println(d1.compareTo(d2)); // 0 = equal, -1 = d1 < d2, 1 = d1 > d2
compareTo()
method must be used for comparison. It returns negative numbers, positive numbers and 0
respectively according to the size of the two values, indicating less than, greater than and equal to respectively.
Notice
Always use compareTo()
to compare the values of two BigDecimals, do not use equals()
!
If you look at the source code of BigDecimal
, you can find that a BigDecimal
is actually represented by a BigInteger
and a scale
, that is, BigInteger
represents a complete integer, and scale
represents the number of decimal places:
java
public class BigDecimal extends Number implements Comparable<BigDecimal> {
private final BigInteger intVal;
private final int scale;
}
BigDecimal
also inherits from Number
and is an immutable object.
Summary
BigDecimal
is used to represent precise decimals and is often used in financial calculations;
To compare BigDecimal
values for equality, you must use compareTo()
instead of equals()
.