BigDecimal es un número decimal con signo de precisión arbitraria inmutable.
Generalmente se usa en campos que requieren alta precisión numérica, como asentamientos de grandes cantidades (porque los números de punto flotante como float y double tienen una precisión insuficiente para representar decimales y solo pueden manejar 16 dígitos significativos), pero su rendimiento de cálculo es menor que Double, Float, etc. En los cálculos numéricos de campo de ingeniería general, BigDecimal no se utilizará casualmente.
Este artículo presentará la suma, resta, multiplicación y división de BigDecimal y 8 modos de redondeo.
Directorio de artículos
Método de construcción
Hay 4 constructores de uso común:
- BigDecimal (valor doble)
- BigDecimal (int val)
- BigDecimal (valor largo)
Los constructores por encima de BigDecimal (String val) obtienen decimales de precisión infinita, es decir, no hay límite para el número de lugares decimales reservados
Estos cuatro constructores pueden construir tipos double, long, int y String como objetos BigDecimal. Primero, se recomienda usar BigDecimal(String val)
, y segundo, no se recomienda usar BigDecimal (double val) para crear, porque double representa 0.1 no es exacto, y si usa new BigDecimal (0.1), el valor obtenido sigue siendo inexacto. Los resultados de su funcionamiento son los siguientes:
Una vez creado el objeto, las operaciones de suma, resta, multiplicación y división no pueden usar directamente +, -, *, /, pero usan los siguientes métodos:
- Suma :, el
add(BigDecimal augend)
retorno es BigDecimal, su valor es (this + augend) - Resta: el
subtract(BigDecimal subtrahend)
retorno es BigDecimal, su valor es (este-sustraendo) - Multiplicación :, el
multiply(BigDecimal multiplicand)
BigDecimal devuelto, su valor es (este * multiplicando) - División :, el
divide(BigDecimal divisor)
BigDecimal devuelto, su valor es (este / divisor), pero no se recomienda
Division recomienda la siguiente API con lugares decimales precisos y un método de transporte claro
divide(BigDecimal divisor, int scale, int roundingMode)
Suma, resta, multiplicación y división
BigDecimal a=new BigDecimal("1000");
BigDecimal b=new BigDecimal("0.001");
//加法: 1000.001
BigDecimal bigDecimal = a.add(b);
//减法:999.999
BigDecimal bigDecimal = a.subtract(b);
//乘法:1.000
BigDecimal bigDecimal = a.multiply(b);
//除法:1000000.000
BigDecimal bigDecimal = a.divide(b);
BigDecimal bigDecimal = a.divide(b,2,RoundingMode.HALF_UP);
Vale la pena señalar que la división generalmente requiere determinar cuántos lugares decimales mantener BigDecimal bigDecimal = a.divide(b,2,RoundingMode.HALF_UP);
. Si no se establece la escala reservada, se puede lanzar ArithmeticException. Esto se debe a que el modo ROUND_UNNECESSARY se a.divide(b)
usa por defecto , es decir, no se realiza ningún redondeo.Si el lugar decimal del resultado del cálculo no coincide con el lugar decimal requerido , se lanzará una excepción.
8 modos de redondeo
1. ROUND_UP
Transporte directo
bigDecimal.setScale(2,BigDecimal.ROUND_UP)
- El primer parámetro newScale:
newScale:2
mantenga 2 lugares decimales - El segundo parámetro BigDecimal.ROUND_UP: transporte directo
tal como:
1000 - 0.011=999.989
BigDecimal.ROUND_UP => 999.99
保留小数点后两位,第二位的“8”进位成“9”,变成了999.99
2. ROUND_DOWN
Descartar decimales adicionales
bigDecimal.setScale(2,BigDecimal.ROUND_DOWN)
- El primer parámetro newScale:
newScale:2
solo mantenga 2 lugares decimales - El segundo parámetro BigDecimal.ROUND_DOWN: descarte los lugares decimales adicionales después del segundo dígito
1000 - 0.011=999.989
BigDecimal.ROUND_DOWN => 999.98
将第二位以后的“9”舍弃,变成了999.98
3. ROUND_CEILING
Subir
bigDecimal.setScale(2,BigDecimal.ROUND_CEILING)
Los números positivos y negativos se manejan de manera diferente: los números positivos se llevan y los números negativos se descartan después del decimal.
- Número positivo 999.989 => 999.99, el segundo "8" lleva
- Número negativo -999.989 => -999.98, se descarta el decimal después del segundo dígito
4. ROUND_FLOOR
Toma el pequeño valor
bigDecimal.setScale(2,BigDecimal.ROUND_FLOOR)
- Número positivo 999.989 => 999.98
- Número negativo -999.989 => -999.99
5. ROUND_HALF_DOWN
Redondo a seis
bigDecimal.setScale(2,BigDecimal.ROUND_HALF_DOWN)
- ROUND_HALF_DOWN: requiere el tercer lugar decimalRedondo a seis (Porque newScale = 2 conserva dos lugares decimales)
por ejemplo:
- 1000-0,005 = 999,995 -> 999,99 cinco rondas
- 1000-0,004 = 999,996 -> 1000,00 seis entradas
6. ROUND_HALF_UP
redondeo
bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP)
- newScale: 2 es para operar en el tercer dígito después del punto decimal
- ROUND_HALF_UP: tercer lugar decimalredondeo
tal como:
- 1000-0,006 = 999,994 -> 999,99 rondas
- 1000-0,005 = 999,995 -> 1000,00 cinco pulgadas
7. ROUND_HALF_EVEN
Esto es un poco mas complicado
Cuando el número descartado <5 descartado,> 5 acarreo , depende de la situación cuando = 5:
bigDecimal.setScale(0,BigDecimal.ROUND_HALF_EVEN)
Sin mantener el punto decimal:
- 5.5 -> 6: Si el dígito izquierdo del número descartado "5" es un número impar , el comportamiento de redondeo es el mismo que ROUND_HALF_UP (redondeo)
- 2.5 -> 2: Si el dígito izquierdo del número descartado "5" es un número par , el comportamiento de redondeo es el mismo que ROUND_HALF_DOWN (Redondo a seis)
- 5.55 -> 6: Si la distancia entre el número descartado "5" y dos números adyacentes (ambos son 5) es igual, entonces redondee al número par adyacente (básicamente también redondeando , como 4.44 -> 4, 6.66 -> 7 )
8.ROUND_UNNECESSARY
El programador puede estar seguro de que el resultado del cálculo es preciso, por lo que no se realiza ningún redondeo. Pero si el número final no cumple con los requisitos de newScale para mantener los lugares decimales, se lanzará ArithmeticException.
bigDecimal.setScale(0,BigDecimal.ROUND_UNNECESSARY)
En el caso de no mantener decimales, seleccione la estrategia ROUND_UNNECESSARY:
digital | Resultados de la |
---|---|
6.6 | ArithmeticException |
6.0 | 6 |
5.5 | ArithmeticException |
5,0 | 5 |