O back-end java implementa cálculo de adição, subtração, multiplicação, divisão e proporção

O back-end java implementa cálculo de adição, subtração, multiplicação, divisão e proporção

A classe API BigDecimal é fornecida no pacote java.math para executar operações precisas em números com mais de 16 dígitos significativos.
O que BigDecimal cria é um objeto, portanto operadores aritméticos como +, -, *, /, etc. não podem ser usados ​​para realizar operações matemáticas diretamente em seu objeto.

Antes de tudo, você precisa entender que o BigDecimal possui 4 métodos de construção:

	//创建一个具有参数所指定整数值的对象
	BigDecimal(int)
	//创建一个具有参数所指定双精度值的对象
	BigDecimal(double)
	//创建一个具有参数所指定整数值的对象
	BigDecimal(long)
	//创建一个具有参数所指定以字符串表示的数值的对象
	BigDecimal(String)

	//这里对比了两种形式,第一种直接value写数字的值,第二种用string来表示
	BigDecimal num1 = new BigDecimal(0.005);
    BigDecimal num2 = new BigDecimal(1000000);
    BigDecimal num3 = new BigDecimal(-1000000);    
    //尽量用字符串的形式初始化
    BigDecimal num12 = new BigDecimal("0.005");
    BigDecimal num22 = new BigDecimal("1000000");
    BigDecimal num32 = new BigDecimal("-1000000");

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

	//加法 add()
    BigDecimal result1 = num1.add(num2);
    BigDecimal result12 = num12.add(num22);
 
    //减法 subtract()
    BigDecimal result2 = num1.subtract(num2);
    BigDecimal result22 = num12.subtract(num22);
 
    //乘法 multiply()
    BigDecimal result3 = num1.multiply(num2);
    BigDecimal result32 = num12.multiply(num22);
 
    //绝对值 abs()
    BigDecimal result4 = num3.abs();
    BigDecimal result42 = num32.abs();
 
    //除法 divide()
    //num1、num12 除数, 20 精确小数位,  BigDecimal.ROUND_HALF_UP 舍入模式
    BigDecimal result5 = num2.divide(num1,20,BigDecimal.ROUND_HALF_UP);
    BigDecimal result52 = num22.divide(num12,20,BigDecimal.ROUND_HALF_UP);

	//去除末尾多余的0:
	new BigDecimal("100.000").stripTrailingZeros().toPlainString();

Envie todos os resultados aqui para ver os resultados
. Há uma diferença aqui, e é por isso que é recomendado usar string para inicialização
insira a descrição da imagem aqui
※ Nota:

1) O número em System.out.println() é do tipo double por padrão, e o cálculo decimal do tipo double é impreciso.

2) Ao utilizar o método de construção da classe BigDecimal para passar no tipo double, o resultado do cálculo também é impreciso!

Como nem todos os números de ponto flutuante podem ser representados com precisão como um valor de tipo duplo, alguns valores de ponto flutuante não podem ser representados com precisão como um valor de tipo duplo, portanto, serão representados como seu valor de tipo duplo mais próximo. Você deve usar o construtor que passa em String. Este ponto é explicado na anotação do construtor da classe BigDecimal.

O parâmetro division divide() usa

Ao usar a função de divisão para dividir, você precisa definir vários parâmetros, casas decimais precisas e modo de arredondamento, caso contrário, ocorrerá um erro.
Podemos ver que os parâmetros da configuração da função de divisão são os seguintes

	//即为(BigDecimal divisor 除数, int scale 精确小数位,  int roundingMode 舍入模式)
	Public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

Mas há muitos tipos de modos de arredondamento BigDecimal.ROUND_XXXX_XXX, o que eles significam especificamente?

Os oito modos de arredondamento são explicados da seguinte forma

1)ROUND_UP

O modo de arredondamento para arredondar a partir de zero.

Sempre incremente o número antes de descartar a parte diferente de zero (sempre adicione 1 ao número anterior à parte diferente de zero descartada).

Observe que esse modo de arredondamento nunca reduz o tamanho do valor calculado.

2)ROUND_DOWN

Modo de arredondamento próximo de zero.

Nunca incremente um número até que uma parte seja descartada (nunca adicione 1 ao número que precede a parte descartada, ou seja, trunca).

Observe que esse modo de arredondamento nunca aumenta o tamanho do valor calculado.

3)ROUND_CEILING

Modo de arredondamento em direção ao infinito positivo.

Se BigDecimal for positivo, o comportamento de arredondamento é o mesmo que ROUND_UP;

Se negativo, o comportamento de arredondamento é o mesmo que ROUND_DOWN.

Observe que esse modo de arredondamento nunca reduz o valor calculado.

4)ROUND_FLOOR

Modo de arredondamento próximo ao infinito negativo.

Se BigDecimal for positivo, o comportamento de arredondamento é o mesmo que ROUND_DOWN;

Estilo negrito Se negativo, o comportamento de arredondamento é o mesmo que ROUND_UP.

Observe que esse modo de arredondamento nunca aumenta o valor calculado.

5)ROUND_HALF_UP

Arredonda para o número "mais próximo" ou para cima se dois números adjacentes forem equidistantes um do outro.

Se a fração descartada for >= 0,5, o comportamento de arredondamento é o mesmo que ROUND_UP; caso contrário, o comportamento de arredondamento é o mesmo que ROUND_DOWN.

Observe que esse é o modo de arredondamento que a maioria de nós aprendeu no ensino fundamental (arredondamento para a metade).

6)ROUND_HALF_DOWN

Um modo de arredondamento que arredonda para o número "mais próximo" ou arredonda para cima se dois números adjacentes estiverem equidistantes um do outro.

Se a fração descartada for > 0,5, o comportamento de arredondamento é o mesmo que ROUND_UP; caso contrário, o comportamento de arredondamento é o mesmo que ROUND_DOWN (arredondado para cima).

7)ROUND_HALF_EVEN

Arredonda para o número "mais próximo" ou para o número par adjacente se a distância para dois números adjacentes for igual.

Se o número à esquerda da parte descartada for ímpar, o comportamento de arredondamento é o mesmo que ROUND_HALF_UP;

Se for par, o comportamento de arredondamento é o mesmo que ROUND_HALF_DOWN.

Observe que esse modo de arredondamento minimiza os erros de acumulação ao repetir uma série de cálculos.

Este modo de arredondamento também é conhecido como "Banker's Rounding" e é usado principalmente nos Estados Unidos. Arredondando para cima, cinco pontos em dois casos.

Se o dígito anterior for um número ímpar, coloque-o, caso contrário, descarte-o.

O exemplo a seguir retém 1 casa decimal, portanto, o resultado desse método de arredondamento.

1,15>1,2 1,25>1,2

8)ROUND_DESNECESSÁRIO

Afirma que a operação solicitada tem um resultado exato, portanto, nenhum arredondamento é necessário.

Uma ArithmeticException será lançada se esse modo de arredondamento for especificado para uma operação que obtém um resultado exato.

Por exemplo: Calcule o resultado de 1÷3 (o último ROUND_UNNECESSARY reportará um erro se o resultado for um decimal infinito)
insira a descrição da imagem aqui
insira a descrição da imagem aqui

2. Compare o tamanho


	//前提为a、b均不能为null
	BigDecimal a = new BigDecimal("xx");
    BigDecimal b = new BigDecimal("xx");
	
	if(a.compareTo(b) == -1){
    
    
	    System.out.println("a小于b");
	}
	 
	if(a.compareTo(b) == 0){
    
    
	    System.out.println("a等于b");
	}
	 
	if(a.compareTo(b) == 1){
    
    
	    System.out.println("a大于b");
	}
	 
	if(a.compareTo(b) > -1){
    
    
	    System.out.println("a大于等于b");
	}
	 
	if(a.compareTo(b) < 1){
    
    
	    System.out.println("a小于等于b");
	}

3. Resumo de BigDecimal

Use BigDecimal quando for necessário um cálculo decimal preciso.O desempenho de BigDecimal é pior do que o de double e float, especialmente ao lidar com operações grandes e complexas. Portanto, não é necessário usar BigDecimal para cálculos gerais de precisão. Tente usar construtores cujo tipo de parâmetro seja String.

BigDecimal é imutável, e um novo objeto será gerado toda vez que as quatro operações aritméticas forem executadas, então lembre-se de salvar o valor após a operação ao fazer adição, subtração, multiplicação e divisão.

Recomendação de ferramenta

package com.vivo.ars.util;
import java.math.BigDecimal;

/**
 * 用于高精确处理常用的数学运算
 */
public class ArithmeticUtils {
    
    
    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 10;

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */

    public static double add(double v1, double v2) {
    
    
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static BigDecimal add(String v1, String v2) {
    
    
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2);
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 保留scale 位小数
     * @return 两个参数的和
     */
    public static String add(String v1, String v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
    
    
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static BigDecimal sub(String v1, String v2) {
    
    
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2);
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1    被减数
     * @param v2    减数
     * @param scale 保留scale 位小数
     * @return 两个参数的差
     */
    public static String sub(String v1, String v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2) {
    
    
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static BigDecimal mul(String v1, String v2) {
    
    
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2);
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被乘数
     * @param v2    乘数
     * @param scale 保留scale 位小数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2, int scale) {
    
    
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return round(b1.multiply(b2).doubleValue(), scale);
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被乘数
     * @param v2    乘数
     * @param scale 保留scale 位小数
     * @return 两个参数的积
     */
    public static String mul(String v1, String v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
     * 小数点以后10位,以后的数字四舍五入
     *
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */

    public static double div(double v1, double v2) {
    
    
        return div(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示需要精确到小数点以后几位
     * @return 两个参数的商
     */
    public static String div(String v1, String v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v1);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static String round(String v, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 小数点后保留几位
     * @return 余数
     */
    public static String remainder(String v1, String v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数  BigDecimal
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 小数点后保留几位
     * @return 余数
     */
    public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
    
    
        if (scale < 0) {
    
    
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 比较大小
     *
     * @param v1 被比较数
     * @param v2 比较数
     * @return 如果v1 大于v2 则 返回true 否则false
     */
    public static boolean compare(String v1, String v2) {
    
    
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        int bj = b1.compareTo(b2);
        boolean res;
        if (bj > 0)
            res = true;
        else
            res = false;
        return res;
    }
}

A lei das coisas boas: Tudo será bom no final, se não for bom, significa que ainda não é o fim.

Acho que você gosta

Origin blog.csdn.net/Cike___/article/details/123049211
Recomendado
Clasificación