El uso de BigDecimal en Java: suma, resta, multiplicación, división, redondeo, comparación, estadísticas de capital

La clase de API BigDecimal proporcionada por Java en el paquete java.math se utiliza para realizar operaciones precisas en números con más de 16 dígitos significativos. La variable de punto flotante de doble precisión double puede manejar 16 dígitos significativos. En aplicaciones prácticas, es necesario realizar operaciones y procesamiento en números mayores o menores. Float y double solo se pueden usar para cálculos científicos o cálculos de ingeniería. Java.math.BigDecimal debe usarse en cálculos comerciales. Lo que BigDecimal crea es un objeto. No podemos usar operadores aritméticos tradicionales como +, -, *, / para realizar operaciones matemáticas directamente en su objeto, pero debemos llamar a su método correspondiente. Los parámetros del método también deben ser objetos de BigDecimal. Constructor es un método especial de la clase, especialmente utilizado para crear objetos, especialmente objetos con parámetros.

1. Método de construcción

Hay 4 métodos de construcción para BigDecimal:

BigDecimal (int): crea un objeto con el valor entero especificado por el parámetro.

BigDecimal (doble): crea un objeto con el valor de doble precisión especificado por el parámetro (no recomendado).

BigDecimal (long): crea un objeto con el valor entero largo especificado por el parámetro.

BigDecimal (String): crea un objeto con el valor numérico representado por la cadena especificada por el parámetro.

¿Por qué no se recomienda el segundo método de construcción? El siguiente 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 del:

La causa del problema: Según la descripción en el JDK, el resultado del método de construcción con un parámetro tipo doble es algo impredecible.

 

2. Suma, resta, multiplicación y división

Operaciones de suma, resta, multiplicación y división BigDecimal.

Adición: utilice el método add ().

Resta: utilice el método restar ().

Multiplicación: utilice el método multiplicar ().

División: utilice el método dividir ().

/**
 * 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 del:

Utilice la biblioteca de clases de la herramienta Hutool para calcular la suma, resta, multiplicación y división de BigDecimal, manteniendo dos lugares decimales.

/**
 * 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 del:

 

3. Redondeo

(1) Redondeo de BigDecimal y dos decimales.

/**
 * 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);
}

Nota: Si está en la industria de las finanzas por Internet, intente utilizar ROUND_HALF_EVEN (método de redondeo bancario) al calcular.

Resultados del:

(2) Redondeo y formateo de salida 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. Comparar tamaño

El tamaño de comparación de BigDecimal puede usar el método compareTo (BigDecimal val), que devuelve el resultado de la siguiente manera:

  • Regresa cuando A es mayor que B: 1
  • Cuando A es igual a B, devuelve: 0
  • Regresa cuando A es 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 del:

 

5. Estadísticas de fondos

Para campos relacionados con fondos, generalmente se usa el tipo de datos BigDecimal.

[Ejemplo] Estadísticas de información sobre el salario del usuario.

/**
 * 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 del:

 

6. Conversión de tipos

(1) Convierta el tipo BigDecimal a otros tipos de datos.

/**
 * 将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 del:

(2) Convertir objeto en 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);
}

 

Supongo que te gusta

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