Skip to main content

2024-07-22

One-liner

Your gentleness is just for me, and my strength is just for you. --- Author Himself · Yi


BigDecimal in Java

In Java, BigDecimal is a class used for high-precision calculations, located in the java.math package. It provides arbitrary precision for floating-point numbers and is suitable for scenarios that require high precision, such as financial and scientific calculations. Compared to the native float and double types, BigDecimal avoids precision loss issues caused by binary floating-point representation.

Here are some key features and common usages of BigDecimal:

1. Creating BigDecimal Objects

You can create BigDecimal objects using strings, integers, floating-point numbers, etc., but it is recommended to use the string constructor to avoid precision issues.

import java.math.BigDecimal;

BigDecimal fromString = new BigDecimal("123.456");
BigDecimal fromInt = new BigDecimal(123);
BigDecimal fromDouble = new BigDecimal(123.456); // Not recommended, may introduce precision issues

2. Common Methods

  • Addition
BigDecimal a = new BigDecimal("10.5");
BigDecimal b = new BigDecimal("2.3");
BigDecimal result = a.add(b); // result: 12.8
  • Subtraction
BigDecimal result = a.subtract(b); // result: 8.2
  • Multiplication
BigDecimal result = a.multiply(b); // result: 24.15
  • Division

When dividing, you need to specify the precision and rounding mode to avoid precision issues.

BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // result: 4.57
  • Comparison
int comparison = a.compareTo(b); // Returns -1 (less than), 0 (equal), 1 (greater than)
  • Rounding
BigDecimal result = a.setScale(0, RoundingMode.HALF_UP); // result: 11

3. Rounding Modes

BigDecimal provides various rounding modes, such as:

  • RoundingMode.UP: Rounds away from zero.
  • RoundingMode.DOWN: Rounds towards zero.
  • RoundingMode.CEILING: Rounds towards positive infinity.
  • RoundingMode.FLOOR: Rounds towards negative infinity.
  • RoundingMode.HALF_UP: Rounds towards the nearest neighbor, or up if equidistant.
  • RoundingMode.HALF_DOWN: Rounds towards the nearest neighbor, or down if equidistant.
  • RoundingMode.HALF_EVEN: Rounds towards the nearest neighbor, or towards the even neighbor if equidistant (banker's rounding).

Example Code

Here is an example of using BigDecimal for basic calculations:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimalExample {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("123.456");
BigDecimal b = new BigDecimal("10.123");

BigDecimal sum = a.add(b);
BigDecimal difference = a.subtract(b);
BigDecimal product = a.multiply(b);
BigDecimal quotient = a.divide(b, 2, RoundingMode.HALF_UP);

System.out.println("Sum: " + sum);
System.out.println("Difference: " + difference);
System.out.println("Product: " + product);
System.out.println("Quotient: " + quotient);
}
}

In high-precision calculations, BigDecimal is a powerful tool, but note that its operations can be slower than native floating-point operations, so consider performance implications in sensitive scenarios.

Using Stream.reduce to Sum a List<BigDecimal>

You can use Java's Stream API to sum a List<BigDecimal>. The Stream API provides a convenient way to perform various operations on collections, including aggregation operations like summing.

Here is a simple example demonstrating how to use the Stream API to sum a List<BigDecimal>:

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

public class BigDecimalSumExample {
public static void main(String[] args) {
List<BigDecimal> numbers = Arrays.asList(
new BigDecimal("10.5"),
new BigDecimal("20.75"),
new BigDecimal("30.25"),
new BigDecimal("40.0")
);

BigDecimal sum = numbers.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);

System.out.println("Sum: " + sum);
}
}

In this example, we use the reduce method to accumulate all elements in the List<BigDecimal>. The reduce method takes two parameters:

  1. Initial value: BigDecimal.ZERO, which is the starting value for the accumulation.
  2. Accumulator function: BigDecimal::add, which is the accumulation operation.

Detailed Explanation

  1. Creating a List<BigDecimal>:

    List<BigDecimal> numbers = Arrays.asList(
    new BigDecimal("10.5"),
    new BigDecimal("20.75"),
    new BigDecimal("30.25"),
    new BigDecimal("40.0")
    );

    Here we create a list containing several BigDecimal values.

  2. Converting the List to a Stream<BigDecimal>:

    numbers.stream()

    Using the stream method, we convert the list to a stream for further operations.

  3. Using the reduce method to sum the elements:

    .reduce(BigDecimal.ZERO, BigDecimal::add)

    The reduce method accumulates all elements in the stream using the specified accumulator function, with BigDecimal.ZERO as the initial value and BigDecimal::add as the accumulator function.

  4. Outputting the result:

    System.out.println("Sum: " + sum);

The output of the above code will be:

Sum: 101.50

This method is concise and efficient, leveraging the advantages of the Stream API to handle various aggregation operations on collections.