O uso de BigDecimal em Java: adição, subtração, multiplicação, divisão, arredondamento, comparação, estatísticas de capital

A classe de API BigDecimal fornecida por Java no pacote java.math é usada para realizar operações precisas em números com mais de 16 dígitos significativos. A variável de ponto flutuante de precisão dupla double pode lidar com 16 dígitos significativos. Em aplicações práticas, é necessário realizar operações e processamento em números maiores ou menores. Float e double só podem ser usados ​​para cálculos científicos ou cálculos de engenharia. Java.math.BigDecimal deve ser usado em cálculos comerciais. O que BigDecimal cria é um objeto. Não podemos usar operadores aritméticos tradicionais como +, -, *, / para realizar operações matemáticas diretamente em seu objeto, mas devemos chamar seu método correspondente. Os parâmetros no método também devem ser objetos de BigDecimal. Construtor é um método especial da classe, especialmente usado para criar objetos, especialmente objetos com parâmetros.

1. Método de construção

Existem 4 métodos de construção para BigDecimal:

BigDecimal (int): Cria um objeto com o valor inteiro especificado pelo parâmetro.

BigDecimal (double): Cria um objeto com o valor de precisão dupla especificado pelo parâmetro (não recomendado).

BigDecimal (long): Cria um objeto com o valor inteiro longo especificado pelo parâmetro.

BigDecimal (String): Crie um objeto com o valor numérico representado pela string especificada pelo parâmetro.

Por que o segundo método de construção não é recomendado? O seguinte código:

/**
 * BigDecimal的构造方法
 * @author pan_junbiao
 */
@Test
public void createBigDecimal()
{
    BigDecimal bigDecimal1 = new BigDecimal(12); //推荐
    BigDecimal bigDecimal2 = new BigDecimal("12.83"); //推荐
    BigDecimal bigDecimal3 = new BigDecimal(12.83); //不推荐

    System.out.println("bigDecimal1的值:" + bigDecimal1);
    System.out.println("bigDecimal2的值:" + bigDecimal2);
    System.out.println("bigDecimal3的值:" + bigDecimal3);
}

Resultados de:

A causa do problema: De acordo com a descrição no JDK, o resultado do método de construção com um parâmetro do tipo double é um tanto imprevisível.

 

2. Adição, subtração, multiplicação e divisão

BigDecimal operações de adição, subtração, multiplicação e divisão.

Adição: use o método add ().

Subtração: use o método subtract ().

Multiplicação: use o método multiply ().

Divisão: use o método divide ().

/**
 * BigDecimal的加减乘除运算
 * @author pan_junbiao
 */
@Test
public void operationTest()
{
    BigDecimal bigDecimal1 = new BigDecimal("10");
    BigDecimal bigDecimal2 = new BigDecimal("2");

    //加法
    BigDecimal addResult = bigDecimal1.add(bigDecimal2);
    System.out.println("加法运算结果:" + addResult);

    //减法
    BigDecimal subResult = bigDecimal1.subtract(bigDecimal2);
    System.out.println("减法运算结果:" + subResult);

    //乘法
    BigDecimal mulResult = bigDecimal1.multiply(bigDecimal2);
    System.out.println("乘法运算结果:" + mulResult);

    //除法
    BigDecimal divResult = bigDecimal1.divide(bigDecimal2);
    System.out.println("除法运算结果:" + divResult);
}

Resultados de:

Use a biblioteca de classes da ferramenta Hutool para calcular adição, subtração, multiplicação e divisão BigDecimal, mantendo duas casas decimais.

/**
 * BigDecimal的加减乘除运算
 * @author pan_junbiao
 */
@Test
public void operationTest()
{
    BigDecimal bigDecimal1 = new BigDecimal("10.2567");
    BigDecimal bigDecimal2 = new BigDecimal("2.236");

    //加法
    BigDecimal addResult = NumberUtil.add(bigDecimal1,bigDecimal2);
    System.out.println("加法运算结果:" + addResult);

    //减法
    BigDecimal subResult = NumberUtil.sub(bigDecimal1,bigDecimal2);
    System.out.println("减法运算结果:" + subResult);

    //乘法
    BigDecimal mulResult = NumberUtil.mul(bigDecimal1,bigDecimal2);
    System.out.println("乘法运算结果:" + mulResult);

    //除法
    BigDecimal divResult = NumberUtil.div(bigDecimal1,bigDecimal2);
    System.out.println("除法运算结果:" + divResult);

    //保留两位小数
    BigDecimal roundResult = NumberUtil.round(bigDecimal1,2);
    System.out.println("保留两位小数:" + roundResult);
}

Resultados de:

 

3. Arredondamento

(1) Arredondamento de BigDecimal e duas casas decimais.

/**
 * BigDecimal的四舍五入,并保留两位小数
 * @author pan_junbiao
 */
@Test
public void roundTest()
{
    BigDecimal bigDecimal1 = new BigDecimal("12.233");
    BigDecimal bigDecimal2 = new BigDecimal("12.288");

    //四舍五入,并保留两位小数
    BigDecimal round1 = bigDecimal1.setScale(2, BigDecimal.ROUND_HALF_UP);
    BigDecimal round2 = bigDecimal2.setScale(2, BigDecimal.ROUND_HALF_UP);

    System.out.println("数值1:" + bigDecimal1);
    System.out.println("四舍五入:" + round1);
    System.out.println("-----------------");
    System.out.println("数值2:" + bigDecimal2);
    System.out.println("四舍五入:" + round2);
}

Observação: se você estiver no setor de finanças da Internet, tente usar ROUND_HALF_EVEN (método de arredondamento bancário) ao fazer o cálculo.

Resultados de:

(2) Saída de arredondamento e formatação de BigDecimal.

/**
 * BigDecimal的四舍五入与格式化输出
 * @author pan_junbiao
 */
@Test
public void formatTest()
{
    // 保留两位小数,个位无数字填充0
    NumberFormat nformat = NumberFormat.getNumberInstance();
    nformat.setMaximumFractionDigits(2);
    System.out.println(nformat.format(0.2));// 0.2
    System.out.println(nformat.format(0.235));// 0.23
    System.out.println(nformat.format(0.2351));// 0.24
    System.out.println(nformat.format(42));// 42

    // DecimalFormat,是NumberFormat的具体实现子类
    // 保留两位小数,对应位上无数字填充0
    DecimalFormat df = new DecimalFormat("#0.00");
    System.out.println(df.format(0.2));// 0.20
    System.out.println(df.format(0.235));// 0.23
    System.out.println(df.format(0.2351));// 0.2, 因为0.2351在0.23-0.24之间,距离0.24更近,所以输出0.24
    System.out.println(df.format(42));// 42.00

    DecimalFormat df4 = new DecimalFormat();
    // #:位置上无数字不显示
    df4.applyPattern("#.##");
    System.out.println(df4.format(345235.0));// 345235
    // 0:位置上无数字显示0
    df4.applyPattern("0.00");
    System.out.println(df4.format(345235.0));// 345235.00
    // 加负数显示
    df4.applyPattern("-0.00");
    System.out.println(df4.format(345235.34567));// -345235.35
    // 逗号分隔
    df4.applyPattern("-0,000.00");
    System.out.println(df4.format(345235.34567));// -345,235.35
    // 百分位
    df4.applyPattern("0.00%");
    System.out.println(df4.format(0.34567));// 34.57%
    // 千分位
    df4.applyPattern("0.00\u2030");
    System.out.println(df4.format(0.34567));// 345.67‰
    // 科学计数法,E之前是底数的格式,E之后的是指数的格式
    df4.applyPattern("0.00E00");
    System.out.println(df4.format(2342.444));// 2.34E03
    // 格式后面加单位符号
    df4.applyPattern("0.00 KG");
    System.out.println(df4.format(2342.444));// 2342.44 KG
    df4.applyPattern("0.00 QA");
    System.out.println(df4.format(2342.444));// 2342.44 QA

    System.out.println(df4.format(2342.435));// 2342.43 QA
    System.out.println(df4.format(2342.445));// 2342.45 QA

    // String.format
    // 保留两位小数,个位数及小数点后两位无数字填充0,四舍五入
    System.out.println(String.format("%.2f", 0.2));// 0.20
    System.out.println(String.format("%.2f", 0.235));// 0.24
    System.out.println(String.format("%.2f", 0.236));// 0.24
    System.out.println(String.format("%.2f", 42.0));// 42.00
}

 

4. Compare o tamanho

O tamanho de comparação de BigDecimal pode usar o método compareTo (BigDecimal val), que retorna o resultado da seguinte maneira:

  • Retorne quando A for maior que B: 1
  • Quando A é igual a B, ele retorna: 0
  • Retorne quando A for menor que B: -1
/**
 * BigDecimal的比较大小
 * @author pan_junbiao
 */
@Test
public void compareTest()
{
    BigDecimal bigDecimal1 = new BigDecimal("12.01");
    BigDecimal bigDecimal2 = new BigDecimal("12.88");
    int result = bigDecimal1.compareTo(bigDecimal2);

    System.out.println("数值1:" + bigDecimal1);
    System.out.println("数值2:" + bigDecimal2);
    System.out.println("数值1与数值2的比较值:" + result);
    System.out.print("数值1与数值2的比较结果:");
    if (result == 1)
    {
        System.out.print("大于");
    }
    else if (result == 0)
    {
        System.out.print("等于");
    }
    else if (result == -1)
    {
        System.out.print("小于");
    }
}

Resultados de:

 

5. Estatísticas de fundos

Para campos relacionados a fundos, o tipo de dados BigDecimal é geralmente usado.

[Exemplo] Estatísticas de informações salariais do usuário.

/**
 * BigDecimal类型的统计
 * @author pan_junbiao
 */
@Test
public void BigDecimalTest()
{
    //获取用户列表
    List<User> userList = UserService.getUserList();
 
    //最高薪资
    BigDecimal maxSalary = userList.stream().map(User::getSalary).max((x1, x2) -> x1.compareTo(x2)).get();
 
    //最低薪资
    BigDecimal minSalary = userList.stream().map(User::getSalary).min((x1, x2) -> x1.compareTo(x2)).get();
 
    //薪资总和
    BigDecimal sumSalary = userList.stream().map(User::getSalary).reduce(BigDecimal.ZERO, BigDecimal::add);
 
    //平均薪资
    BigDecimal avgSalary = userList.stream().map(User::getSalary).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(userList.size()), 2, BigDecimal.ROUND_HALF_UP);
 
    //打印统计结果
    System.out.println("最高薪资:" + maxSalary + "元");
    System.out.println("最低薪资:" + minSalary + "元");
    System.out.println("薪资总和:" + sumSalary + "元");
    System.out.println("平均薪资:" + avgSalary + "元");
}

Resultados de:

 

6. Tipo de conversão

(1) Converta o tipo BigDecimal em outros tipos de dados.

/**
 * 将BigDecimal类型转换成其他数据类型
 * @author pan_junbiao
 */
@Test
public void convertTest()
{
    BigDecimal bigDecimal = new BigDecimal("12.88");

    //字符串
    String toString = bigDecimal.toString();
    System.out.println("字符串:" + toString);

    //double值
    double toDouble  =bigDecimal.doubleValue();
    System.out.println("double值:" + toDouble);

    //float值
    float toFloat = bigDecimal.floatValue();
    System.out.println("float值:" + toFloat);

    //long值
    long toLong = bigDecimal.longValue();
    System.out.println("long值:" + toLong);

    //int值
    int toInt = bigDecimal.intValue();
    System.out.println("int值:" + toInt);
}

Resultados de:

(2) Converta o objeto no tipo BigDecimal.

/**
 * 将Object对象转换成BigDecimal类型
 */
public static BigDecimal toBigDecimal(Object obj)
{
    BigDecimal result = new BigDecimal(0);
    if (obj != null)
    {
        if (obj instanceof BigDecimal)
        {
            result = (BigDecimal) obj;
        }
        else if (obj instanceof String)
        {
            result = new BigDecimal((String) obj);
        }
        else if (obj instanceof BigInteger)
        {
            result = new BigDecimal((BigInteger) obj);
        }
        else if (obj instanceof Number)
        {
            result = new BigDecimal(((Number) obj).doubleValue());
        }
        else
        {
            throw new ClassCastException("Not possible to coerce [" + obj + "] from class " + obj.getClass() + " into a BigDecimal.");
        }
    }
    return result.setScale(2, BigDecimal.ROUND_HALF_UP);
}

 

Acho que você gosta

Origin blog.csdn.net/pan_junbiao/article/details/111406241
Recomendado
Clasificación